Instantly share code, notes, and snippets.

@etam /monitor.cpp
Last active Aug 29, 2015

Embed
What would you like to do?
C++14 monitor class with multiple readers, single writers access control
/*
Based on Herb Sutter's monitor implementation presented on
https://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Herb-Sutter-Concurrency-and-Parallelism at 40:30,
which is, I hope, public domain.
*/
#include <utility>
#include <shared_mutex>
template <class T>
class monitor
{
private:
T obj;
typedef std::shared_timed_mutex mutex_type; // You can also use boost::shared_mutex, or std::shared_mutex from C++17
mutable mutex_type shared_mutex;
public:
monitor() = default;
explicit
monitor(const T& _obj)
: obj{_obj}
{}
explicit
monitor(T&& _obj)
: obj{std::move(_obj)}
{}
monitor(const monitor&) = delete;
monitor& operator=(const monitor&) = delete;
template <typename F>
auto exec_ro(F f) const // add "-> decltype(f(obj))" for C++11
{
std::shared_lock<mutex_type> shared_lock{shared_mutex};
return f(obj);
}
template <typename F>
auto exec_rw(F f)
{
std::unique_lock<mutex_type> unique_lock{shared_mutex};
return f(obj);
}
};
// example usage:
// compile with g++ -std=c++14 example.cpp -o example -fopenmp
#include <iostream>
#include "monitor.hpp"
int main()
{
monitor<int> mi{5};
#pragma omp parallel num_threads(4)
#pragma omp parallel
mi.exec_ro([](const int& i) {
std::cout << "The value is " << i << std::endl;
std::cout << "This will " << "overlap with " << "other threads" << std::endl;
});
#pragma omp parallel
mi.exec_rw([](int& i){
std::cout << "The value is " << i << std::endl;
std::cout << "We increment the value" << std::endl;
++i;
std::cout << "This will not " << "overlap with " << "other threads" << std::endl;
std::cout << "The value is now " << i << std::endl;
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment