Skip to content

Instantly share code, notes, and snippets.

@Newlifer
Last active June 23, 2017 09:57
Show Gist options
  • Save Newlifer/5c94c5913db4b8aa911951505fb5b3a3 to your computer and use it in GitHub Desktop.
Save Newlifer/5c94c5913db4b8aa911951505fb5b3a3 to your computer and use it in GitHub Desktop.
lock.cpp
#include <mutex>
namespace aim {
template <typename T>
struct MutexLock {
using value_type = typename T::value_type;
using container_type = T;
MutexLock()
{}
MutexLock(const MutexLock&) = delete;
value_type read() {
mutex.lock();
auto result = container.pop();
mutex.unlock();
return result;
}
void write(value_type&& value) {
mutex.lock();
container.push(std::move(value));
mutex.unlock();
}
value_type read_keep_lock() {
mutex.lock();
return container.pop();
}
void write_locked(value_type&& value) {
container.push(std::move(value));
mutex.unlock();
}
private:
std::mutex mutex;
container_type container;
};
}
#include <iostream>
#include <unordered_map>
#include <queue>
#include <string>
#include <thread>
template <typename T=std::size_t>
struct ValueContainer {
using value_type = T;
value_type front() {
return value_;
}
value_type pop() {
return value_;
}
void push(value_type&& value) {
value_ = value;
}
private:
value_type value_ = 0;
};
template <typename T, template <typename...> class Subcontainer>
struct Queue {
using subcontainer_t = Subcontainer<T>;
using value_type = T;
value_type front() const {
return cnt.front();
}
value_type pop() {
auto ret = cnt.front();
cnt.pop();
return ret;
}
void push(value_type&& value) {
cnt.push(std::move(value));
}
private:
subcontainer_t cnt;
};
template <typename T>
using Queue_t = Queue<T, std::queue>;
aim::MutexLock<ValueContainer<std::size_t>> counter_container;
void inc() {
auto&& value = counter_container.read_keep_lock();
value += 1;
counter_container.write_locked(std::move(value));
}
std::mutex io_mutex;
void writter(const std::string& name, int value) {
do {
io_mutex.lock();
std::cout << "Workning on " << name << " with value " << value << "\n";
io_mutex.unlock();
} while (counter_container.read() >= 2);
}
std::unordered_map<std::string, aim::MutexLock<Queue_t<int>>> queue_collection;
void foo(const std::string& queue_name) {
while (true) {
auto&& value = queue_collection[queue_name].read();
writter(queue_name, value);
value *= 10;
if (value > 1000) {
inc();
return;
}
queue_collection[queue_name].write(std::move(value));
}
}
int main() {
const std::string first = "first";
const std::string second = "second";
queue_collection[first].write(12);
queue_collection[first].write(13);
queue_collection[first].write(14);
queue_collection[second].write(19);
std::thread first_thread(foo, first);
std::thread second_thread(foo, second);
first_thread.join();
second_thread.join();
std::cout << counter_container.read() << "\n";
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment