天天看點

linux mutex 鎖、條件變量簡單封裝使用

封裝

#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include <stdio.h>

//g++  mutex.cpp  -lpthread -lrt

class CMutex
{
public:
    CMutex()
    {
        pthread_mutex_init(&m_lock, NULL);
    }
    ~CMutex()
    {
        pthread_mutex_destroy(&m_lock);
    }
    bool lock()
    {
        return  (0 == pthread_mutex_lock(&m_lock));
    }
    bool unLock()
    {
        return  (0 == pthread_mutex_unlock(&m_lock));
    }
    bool tryLock()
    {
        return (0 == pthread_mutex_trylock(&m_lock));
    }
private:
    pthread_mutex_t m_lock;
    friend class CCond;
};

class CCond
{
public:
    CCond()
    {
        pthread_cond_init(&m_cond, NULL);
    }
    ~CCond()
    {
        pthread_cond_destroy(&m_cond);
    }
    void wait(CMutex* pMutex)
    {
        pthread_cond_wait(&m_cond, &(pMutex->m_lock));
    }
    void timedwait(CMutex* pMutex,long seconds,long nanoseconds = 0)
    {
        struct timespec t;
        clock_gettime(CLOCK_REALTIME, &t);
        t.tv_sec += seconds;
        t.tv_nsec += nanoseconds;
        pthread_cond_timedwait(&m_cond, &(pMutex->m_lock),&t);
    }
    void wake()
    {
        pthread_cond_signal(&m_cond);
    }
    void broadcast()
    {
        pthread_cond_broadcast(&m_cond);
    }
private:
    pthread_cond_t m_cond;
};

class CMutexLocker
{
public:
    CMutexLocker(CMutex* pMutex)
    {
        mp_mutex = pMutex;
        if(mp_mutex){
            mp_mutex->lock();
        }
    }
    ~CMutexLocker()
    {
        if(mp_mutex){
            mp_mutex->unLock();
        }
    }
private:
    CMutex* mp_mutex;
};

class CMutexTryLocker
{
public:
    CMutexTryLocker(CMutex* pMutex)
    {
        m_isLock = false;
        mp_mutex = pMutex;
        if(mp_mutex){
            m_isLock = mp_mutex->tryLock();
        }
    }
    bool isLock() const
    {
        return m_isLock;
    }
    ~CMutexTryLocker()
    {
        if(mp_mutex && m_isLock){
            mp_mutex->unLock();
        }
    }
private:
    bool    m_isLock;
    CMutex* mp_mutex;
};
           

測試

static CMutex g_mutex;
static CCond  g_cond;
static int    g_num = 10;
bool decnum()
{
    CMutexLocker lock(&g_mutex);
    while(1){
        if(g_num > 0){
            g_num--;
            printf("num=%d\n",g_num);
            return  true;
        }else{
            g_cond.wait(&g_mutex);
            //g_cond.timedwait(&g_mutex,3);
        }
    }
    return  false;
}

bool addnum()
{
    CMutexLocker lock(&g_mutex);
    g_num++;
    g_cond.wake();
    return  true;
}

void* test(void* arg)
{
    pthread_detach(pthread_self());
    while(1){
        decnum();
    }
}

void* test1(void* arg)
{
    while(1){
        addnum();
        sleep(5);
    }

}

int main()
{
    pthread_t th;
    for(int i = 0;i < 10;i++){
        if (pthread_create(&th, NULL, test, NULL) != 0){
            perror("建立處理線程失敗:");
            return -1;
        }
    }

    for(int i = 0;i < 5;i++){
        if (pthread_create(&th, NULL, test1, NULL) != 0){
            perror("建立處理線程失敗:");
            return -1;
        }
    }
    pthread_join(th,NULL);
    return 0;
}
           

結果

[[email protected] mutex]# g++  mutex.cpp  -lpthread -lrt
[[email protected] mutex]# ./a.out 
num=9
num=8
num=7
num=6
num=5
num=4
num=3
num=2
num=1
num=0
num=0
num=0
num=0
num=0
num=0
num=4
num=3
num=2
num=1
num=0

           

繼續閱讀