设计模式C++实现:监视器对象
2016-03-17 20:14
302 查看
监视器对象设计模式使并发方法的执行同步化,以确保任一时刻仅有一个方法在对象内运行。别名线程安全被动对象。
问题场景:应用程序包含被多个线程并发调用的对象。这些方法通常修改其对象的内部状态。为了并发线程内正确执行,有必要对对象的访问进行同步和调度。如果客户机必须显示的获取和释放底层同步机制,如信号、互斥或条件变量。那么并发应用程序更难编程。因此,对象应该负责确保它们需要同步的任何方法被透明的串行化。
代码示例:
问题场景:应用程序包含被多个线程并发调用的对象。这些方法通常修改其对象的内部状态。为了并发线程内正确执行,有必要对对象的访问进行同步和调度。如果客户机必须显示的获取和释放底层同步机制,如信号、互斥或条件变量。那么并发应用程序更难编程。因此,对象应该负责确保它们需要同步的任何方法被透明的串行化。
代码示例:
#include <iostream> #include <string> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <pthread.h> using namespace std; class Mutex { public: Mutex() { pthread_mutex_init(&_lock, NULL); } virtual ~Mutex() { pthread_mutex_destroy(&_lock); } void Lock() { pthread_mutex_lock(&_lock); } void Unlock() { pthread_mutex_unlock(&_lock); } pthread_mutex_t* GetLock() { return &_lock; } private: pthread_mutex_t _lock; }; class TreadCond { public: TreadCond() { pthread_cond_init(&m_cond, NULL); } virtual ~TreadCond() { pthread_cond_destroy(&m_cond); } void CondNotify() { pthread_cond_signal(&m_cond); } void CondWait(pthread_mutex_t* lock) { pthread_cond_wait(&m_cond, lock); } private: pthread_cond_t m_cond; }; class ScopedLock { public: ScopedLock( Mutex& mutex_obj ) : _mutex_obj(mutex_obj) { _mutex_obj.Lock(); } ~ScopedLock() { _mutex_obj.Unlock(); } private: Mutex& _mutex_obj; }; class MessageQueue { enum {MAX_SIZE = 100,}; public: MessageQueue(int size = MAX_SIZE): m_size(size), m_mesageCount(0) { } ~MessageQueue() { delete m_array; } void put(int value) { ScopedLock lock(m_mutex); while(i_full()) { m_notFullCond.CondWait(m_mutex.GetLock()); cout<<"full"<<endl; } i_put(value); //cout<<"put:"<<value<<endl; m_notEmptyCond.CondNotify(); } int get() { ScopedLock lock(m_mutex); while(i_empt()) { m_notEmptyCond.CondWait(m_mutex.GetLock()); cout<<"empt"<<endl; } int value = i_get(); //cout<<"get:"<<value<<endl; m_notFullCond.CondNotify(); return value; } bool empt() { ScopedLock lock(m_mutex); return i_empt(); } bool full() { ScopedLock lock(m_mutex); return i_full(); } private: bool i_empt() { return m_mesageCount == 0; } bool i_full() { return m_mesageCount == m_size; } void i_put(int value) { m_array[m_mesageCount] = value; m_mesageCount++; //cout<<"putmsgcout:"<<m_mesageCount<<endl; } int i_get() { int val = m_array[m_mesageCount-1];; m_mesageCount--; //cout<<"getmsgcout:"<<m_mesageCount<<endl; return val; } private: int m_size; int m_array[MAX_SIZE]; int m_mesageCount; Mutex m_mutex; TreadCond m_notEmptyCond; TreadCond m_notFullCond; }; MessageQueue g_queue; void *pthr_fun1(void *arg) { int i = 1; while(i < 30000) { g_queue.put(i); cout<<"thread1_put:"<<i<<endl; i++; } } void *pthr_fun2(void *arg) { int i = 0; int value = 0; while(i < 10000) { value = g_queue.get(); cout<<"thread2_get:"<<value<<endl; i++; } } void *pthr_fun3(void *arg) { int i = 0; int value = 0; while(i < 10000) { value = g_queue.get(); cout<<"thread3_get:"<<value<<endl; i++; } } void *pthr_fun4(void *arg) { int i = 0; int value = 0; while(i < 10000) { value = g_queue.get(); cout<<"thread4_get:"<<value<<endl; i++; } } int main () { pthread_t thread1, thread2, thread3, thread4; pthread_create(&thread1,NULL,pthr_fun1,NULL);\ pthread_create(&thread2,NULL,pthr_fun2,NULL);\ pthread_create(&thread3,NULL,pthr_fun3,NULL);\ pthread_create(&thread4,NULL,pthr_fun4,NULL);\ pthread_join(thread1,NULL); pthread_join(thread2,NULL); pthread_join(thread3,NULL); pthread_join(thread4,NULL); return 0; }
相关文章推荐
- .NET中保证线程安全的高级方法Interlocked类使用介绍
- Java线程安全中的单例模式
- 深入线程安全容器的实现方法
- PHP 线程安全与非线程安全版本的区别深入解析
- 深入理解线程安全与Singleton
- 多线程问题及处理方法【转】
- Java之线程安全的简单理解
- android的线程安全
- ConcurrentHashMap并不是绝对线程安全的
- Springmvc并发访问的线程安全性问题
- Servlet和 Struts线程安全问题
- Spring Bean 中的线程安全
- 线程安全的单例模式
- java 3S
- JAVA 并发编程- Spring 并发访问的线程安全性问题
- Spring AOP的案例
- 成员变量与线程安全
- String,StringBuffer与StringBuilder的区别??
- 黑马程序员---第四讲 多线程的应用(2)
- struts2、spring多用户线程混乱