您的位置:首页 > 编程语言 > C语言/C++

设计模式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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息