transacciones taller relación qué programación programacion porque por necesaria lectores las importante guardan estilo escritores concurrente con atomocidad algoritmo c++ multithreading templates boost concurrency

taller - Haciendo una clase C++ un Monitor(en el sentido concurrente)



qué relación guardan las transacciones con la programación concurrente y la atomocidad (1)

Quiero asegurarme de que solo un hilo a la vez pueda ejecutar un método de mi clase C ++. En otras palabras, haz que la clase se comporte como un Monitor .

¿Hay un patrón, una forma de usar estantes para hacer esto o alguna clase de Boost que pueda usar? Porque mi única idea hasta ahora es agregar un miembro de la Sección Crítica, y adquirirlo al comienzo de cada método y liberarlo al final (usando RAII, por supuesto). Pero eso parece muy redundante, y no puedo reutilizarlo para alguna otra clase.


Primero haz una clase de monitor genérico. Con la potencia de C ++ 11 puedes hacerlo de la manera más simple:

template <class F> struct FunctionType; template <class R, class Object, class... Args> struct FunctionType<R (Object::*)(Args...)> { typedef R return_type; }; template <class R, class Object, class... Args> struct FunctionType<R (Object::*)(Args...) const> { typedef R return_type; }; template <class Object_> class Monitor { public: typedef Object_ object_type; template <class F, class... Args > typename FunctionType<F>::return_type operation(const F& f, Args... args) { critical_section cs; return (object.*f)(args...); } template <class F, class... Args > typename FunctionType<F>::return_type operation(const F& f, Args... args) const { critical_section cs; return (object.*f)(args...); } private: object_type object; class critical_section {}; };

Por supuesto, critical_section implementación de critical_section depende de usted. Recomiendo POSIX o algunos BOOST.

Está listo para usar en este momento:

Monitor<std::vector<int> > v; v.operation((void (std::vector<int>::*)(const int&)) &std::vector<int>::push_back, 1); v.operation((void (std::vector<int>::*)(const int&)) &std::vector<int>::push_back, 2); size = v.operation(&std::vector<int>::size); std::cout << size << std::endl;

Como puede ver, a veces deberá indicar explícitamente a qué función de miembro desea llamar, std :: vector <> tiene más de un push_back ...

Para los compiladores que todavía no admiten la plantilla variadic, la solución sin ella a continuación, tengo tiempo para hasta dos argumentos, es muy inconveniente, si es necesario, agregar la función con más argumentos:

template <class F> struct FunctionType; template <class R, class Object> struct FunctionType<R (Object::*)()> { typedef R return_type; }; template <class R, class Object> struct FunctionType<R (Object::*)() const> { typedef R return_type; }; template <class R, class Object, class Arg1> struct FunctionType<R (Object::*)(Arg1)> { typedef R return_type; }; template <class R, class Object, class Arg1> struct FunctionType<R (Object::*)(Arg1) const> { typedef R return_type; }; template <class R, class Object, class Arg1, class Arg2> struct FunctionType<R (Object::*)(Arg1,Arg2)> { typedef R return_type; }; template <class R, class Object, class Arg1, class Arg2> struct FunctionType<R (Object::*)(Arg1,Arg2) const> { typedef R return_type; }; template <class Object_> class Monitor { public: typedef Object_ object_type; template <class F> typename FunctionType<F>::return_type operation(const F& f) { critical_section cs; return (object.*f)(); } template <class F> typename FunctionType<F>::return_type operation(const F& f) const { critical_section cs; return (object.*f)(); } template <class F, class Arg1> typename FunctionType<F>::return_type operation(const F& f, Arg1 arg1) { critical_section cs; return (object.*f)(arg1); } template <class F, class Arg1> typename FunctionType<F>::return_type operation(const F& f, Arg1 arg1) const { critical_section cs; return (object.*f)(arg1); } template <class F, class Arg1, class Arg2> typename FunctionType<F>::return_type operation(const F& f, Arg1 arg1, Arg2 arg2) { critical_section cs; return (object.*f)(arg1, arg2); } template <class F, class Arg1, class Arg2> typename FunctionType<F>::return_type operation(const F& f, Arg1 arg1, Arg2 arg2) const { critical_section cs; return (object.*f)(arg1, arg2); } private: object_type object; class critical_section {}; };