设计模式C++实现:监视器对象

来源:互联网 发布:h3c查看端口状态命令 编辑:程序博客网 时间:2024/06/06 23:52

监视器对象设计模式使并发方法的执行同步化,以确保任一时刻仅有一个方法在对象内运行。别名线程安全被动对象。

问题场景:应用程序包含被多个线程并发调用的对象。这些方法通常修改其对象的内部状态。为了并发线程内正确执行,有必要对对象的访问进行同步和调度。如果客户机必须显示的获取和释放底层同步机制,如信号、互斥或条件变量。那么并发应用程序更难编程。因此,对象应该负责确保它们需要同步的任何方法被透明的串行化。
代码示例:

#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;}
0 0
原创粉丝点击