zoukankan      html  css  js  c++  java
  • linux条件变量使用和与信号量的区别

    近来在项目中用到条件变量和信号量做同步时,这一块一直都有了解,但也一直没有总结,这次总结一下,给大家提供点参考,也给自己留点纪念。

    首先,关于信号量和条件变量的概念可以自行查看APUE,我这直接把APUE中的代码拿过来对比;

    一,条件变量的使用:

    #include <pthread.h>
    
    struct msg {
        struct msg *m_next;
        /* ... more stuff here ... */
    };
    struct msg *workq;
    pthread_cond_t qready = PTHREAD_COND_INITIALIZER;
    pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;
    
    void
    process_msg(void)
    {
        struct msg *mp;
    
        for (;;) {
            pthread_mutex_lock(&qlock);
            while (workq == NULL)
                pthread_cond_wait(&qready, &qlock);
            mp = workq;
            workq = mp->m_next;
            pthread_mutex_unlock(&qlock);
            /* now process the message mp */
        }
    }
    
    void
    enqueue_msg(struct msg *mp)
    {
        pthread_mutex_lock(&qlock);
        mp->m_next = workq;
        workq = mp;
        pthread_mutex_unlock(&qlock);
        pthread_cond_signal(&qready);
    }

    当然,在触发条件变量时也可以用以下代码,两种方式各有优劣,具体可以参考:https://www.cnblogs.com/charlesblc/p/6143397.html

    void
    enqueue_msg(struct msg *mp)
    {
        pthread_mutex_lock(&qlock);
        mp->m_next = workq;
        workq = mp;
        pthread_cond_signal(&qready);
        pthread_mutex_unlock(&qlock);
    }

    二,工作中的使用:

    typedef struct _STAT
    {
        int b_stop;
        MDL_COND_T cond;
    }STAT;
    STAT g_enc_stat;
    pthread_mutex_t mutex;
    pthread_cond_t cond;//可以放在结构体里面
    pthread_cond_init(&cond);
    pthread_mutex_init(&mutex);
    int dsp_thread_start(unsigned int trmn)
    {
        
        pthread_mutex_lock(&mutex);
        ...
        if(1 == g_enc_stat.b_stop)
        {
       
          g_enc_stat.b_stop = 0;
          pthread_cond_signal(&cond); 
         
        }
        pthread_mutex_unlock(&mutex);
        return OK;
    }
    
    
    /**************************************
    * @fn        
    * @brief    
    * @param   
    * @return  
    * @other 
    ***************************************/
    int dsp_thread_stop(unsigned int trmn)
    {
        
        pthread_mutex_lock(&mutex);
        ...
        g_enc_stat.b_stop = 1;
        pthread_mutex_unlock(&mutex);
        return OK;
    }
    void dsp_thread(void)
    {
     for(;;)
    {
    pthread_mutex_lock(
    &mutex);//不仅用于同步,还可以用于stop时互斥(线程执行时原子操作) if(g_enc_stat.b_stop) { pthread_cond_wait(&cond,&mutex); pthread_mutex_unlock(&mutex);//这个地方也可以不用,参考上述代码,直接执行下面 continue; } . . . pthread_mutex_unlock(&mutex);
    } }

    三,条件变量和信号量的区别:

    (1)使用条件变量可以一次唤醒所有等待者,而这个信号量没有的功能,感觉是最大区别。

    (2)信号量是有一个值(状态的),而条件变量是没有的,没有地方记录唤醒(发送信号)过多少次,也没有地方记录唤醒线程(wait返回)过多少次。从实现上来说一个信号量可以是用mutex + counter + condition variable实现的。因为信号量有一个状态,如果想精准的同步,那么信号量可能会有特殊的地方。信号量可以解决条件变量中存在的唤醒丢失问题。

    (3)在Posix.1基本原理一文声称,有了互斥锁和条件变量还提供信号量的原因是:“本标准提供信号量的而主要目的是提供一种进程间同步的方式;这些进程可能共享也可能不共享内存区。互斥锁和条件变量是作为线程间的同步机制说明的;这些线程总是共享(某个)内存区。这两者都是已广泛使用了多年的同步方式。每组原语都特别适合于特定的问题”。尽管信号量的意图在于进程间同步,互斥锁和条件变量的意图在于线程间同步,但是信号量也可用于线程间,互斥锁和条件变量也可用于进程间。应当根据实际的情况进行决定。信号量最有用的场景是用以指明可用资源的数量。

    经典的一句话:

     互斥量是信号量的一种特例,互斥量的本质是一把锁。A mutex is basically a lock that we set (lock) before accessing a shared resource and release (unlock) when we're done

    四,互斥锁的巧用:

    func a{
         lock;
         temp_time_id = m_time_id;
         m_time_id  = 0;
         unlock;//不仅减少锁的颗粒度,也能减少死锁,因为detach会等待一个定时器回调,但定时器回调也会加锁,类似于lock->A -> B->lock;
         if(0 != temp_time_id)  
             CTime::getinstance->detach(temp_time_id)    
    }
  • 相关阅读:
    《人件》读书笔记
    《人月神话》读书笔记
    使用表驱动编程设计打印万年历
    maven spring整合mybatis是使用junit测试报字节序列的错误
    idea中建立maven web项卡在Generating Project in Batch mode
    ideaIU-2016.2.5激活
    maven初步入门demo
    Scala基础篇-04 try表达式
    面试题12-旋转数组的最小值
    scala基础篇-03 if与for
  • 原文地址:https://www.cnblogs.com/kwdeblog/p/12169177.html
Copyright © 2011-2022 走看看