Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <future>
- #include <mutex>
- #include <numeric>
- #include <queue>
- #include <string>
- #include <thread>
- #include <vector>
- #include "test_framework.h"
- using namespace std;
- template <typename T>
- class Synchronized {
- public:
- explicit Synchronized(T initial = T()) : value_(move(initial)) {};
- struct Access {
- T& ref_to_value;
- lock_guard<mutex> lock_guard_mutex;
- };
- Access GetAccess() {
- return {value_,
- lock_guard(mutex_)};
- }
- private:
- T value_;
- mutex mutex_;
- };
- void TestConcurrentUpdate() {
- Synchronized<string> common_string;
- const size_t add_count = 50000;
- auto updater = [&common_string, add_count] {
- for (size_t i = 0; i < add_count; ++i) {
- auto access = common_string.GetAccess();
- access.ref_to_value += 'a';
- }
- };
- auto f1 = async(updater);
- auto f2 = async(updater);
- f1.get();
- f2.get();
- ASSERT_EQUAL(common_string.GetAccess().ref_to_value.size(), 2 * add_count);
- }
- vector<int> Consume(Synchronized<deque<int>>& common_queue) {
- vector<int> got;
- for (;;) {
- deque<int> q;
- {
- auto access = common_queue.GetAccess();
- q = move(access.ref_to_value);
- }
- for (int item : q) {
- if (item > 0) {
- got.push_back(item);
- } else {
- return got;
- }
- }
- }
- }
- void TestProducerConsumer() {
- Synchronized<deque<int>> common_queue;
- auto consumer = async(Consume, ref(common_queue));
- const size_t item_count = 100000;
- for (size_t i = 1; i <= item_count; ++i) {
- common_queue.GetAccess().ref_to_value.push_back(i);
- }
- common_queue.GetAccess().ref_to_value.push_back(-1);
- vector<int> expected(item_count);
- iota(begin(expected), end(expected), 1);
- ASSERT_EQUAL(consumer.get(), expected);
- }
- int main() {
- Synchronized<int> s_int;
- {
- auto access = s_int.GetAccess();
- access.ref_to_value = 5;
- }
- ASSERT_EQUAL(s_int.GetAccess().ref_to_value, 5);
- }
Advertisement
Add Comment
Please, Sign In to add comment