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( == g_enc_stat.b_stop)
{ g_enc_stat.b_stop = ;
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 = ;
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
linux条件变量使用和与信号量的区别的更多相关文章
- 理解 Linux 条件变量
理解 Linux 条件变量 1 简介 当多个线程之间因为存在某种依赖关系,导致只有当某个条件存在时,才可以执行某个线程,此时条件变量(pthread_cond_t)可以派上用场.比如: 例1: 当系统 ...
- 进程间通信机制(管道、信号、共享内存/信号量/消息队列)、线程间通信机制(互斥锁、条件变量、posix匿名信号量)
注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料如<linux内核完全剖析>.<linux c 编程一站式学习>等,只是为了更好 ...
- linux 条件变量与线程池
条件变量Condition Variables 概述 1. 条件变量提供了另外一种线程同步的方式.如果没有条件变量,程序需要使用线程连续轮询(可能在临界区critical section内)方式检查条 ...
- linux 条件变量
互斥量就是一把锁,在访问数据时能保证同一时间内只有一个线程访问数据,在访问完以后再释放互斥量上的锁. 条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条 ...
- linux条件变量
条件变量用于线程之间的通信,和互斥锁一起使用.条件变量用于及时通知等待的线程条件的变化,使线程不至于错过变化. 考虑下面的情况,有AB两个线程对index这个全局变量进行++,一个线程C用于判断,in ...
- Linux 条件变量函数signal和wait补充
pthread_cond_wait必须放在pthread_mutex_lock和pthread_mutex_unlock之间,因为他要根据共享变量的状态来觉得是否要等待,而为了不永远等待下去所以必须要 ...
- go条件变量的使用和原理
场景 最近写代码时碰到一个场景, 需要使用 map[int]struct{} 结构来存储task, map的key是task的id,随时可以增减.因为的确除了看书,基本上没使用过条件变量所以后面过了一 ...
- [转]一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程
一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程 希望此文能给初学多线程编程的朋友带来帮助,也希望牛人多多指出错误. 另外感谢以下链接的作者给予,给我的学习带来了很大帮助 http ...
- Linux同步机制(二) - 条件变量,信号量,文件锁,栅栏
1 条件变量 条件变量是一种同步机制,允许线程挂起,直到共享数据上的某些条件得到满足. 1.1 相关函数 #include <pthread.h> pthread_cond_t cond ...
随机推荐
- H3C 802.11协议的发展
- Python--day69--ORM聚合查询和分组查询
聚合查询和分组查询 聚合 aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典. 键的名称是聚合值的标识符,值是计算出来的聚合值.键的名称是按照字段和聚合 ...
- springboot activiti工作流简单示例
最近一直研究springboot,根据工作需求,工作流需要作为一个单独的微服务工程来提供给其他服务调用,现在简单的写下工作流(使用的activiti)微服务的搭建与简单使用 jdk:1.8 数据库:m ...
- 深入理解String、StringBuffer、StringBuilder(转)
文章系转载,非原创,原地址: http://www.cnblogs.com/dolphin0520/p/3778589.html 相信String这个类是Java中使用得最频繁的类之一,并且又是各大公 ...
- POJ 2251宽搜、
因为这个题做了两次犯了两次不同的错误. 第一次用的dfs死活都超时 第二次把定义队列定义在了全局变量的位置,导致连WA了几次.最后找到原因的我真的想一巴掌拍死自己 #include<cstdio ...
- pycharm解析器找不到
pycharm每个项目都需要设定解释器位置吧,把自己解释器位置添加到项目设置就好了 先装python,再装pycharm,不然找不到解析器的,解析器其实就是python.exe.
- POI 导入、导出Excel
POI,全称Apache POI,是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能.项目地址:Apache POI - t ...
- Python--day37--守护进程和几个常用的方法
1,p.daemon = True #设置子进程为守护进程 #守护进程会随着主进程的代码执行完毕 而结束 #子进程 --> 守护进程 import time from multiprocessi ...
- win10 uwp 使用 Azure DevOps 自动构建
通过 Azure DevOps 可以做到自动构建程序,覆盖计划.创建.编程.测试.部署.发布.托管.共享等各个环节,适用于大多数的语言.平台. 本文继续使用图床为例告诉大家如何使用 Azure Dev ...
- linux模块加载竞争
到目前, 我们的讨论已来到一个模块加载的重要方面: 竞争情况. 如果你在如何编写你的 初始化函数上不小心, 你可能造成威胁到整个系统的稳定的情形. 我们将在本书稍后讨论 竞争情况; 现在, 快速提几点 ...