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

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

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

#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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章