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 ...
随机推荐
- css中background和 background-color 同时使用的优先级
给背景图片设置一个默认背景颜色,有以下两种方法: <style> .bg1{ background:url(http://debug.itxst.com/img/logo.png) red ...
- 自定义element树表格图标
如下图: css代码: /deep/.el-icon-arrow-right:before { content: "\e6d9"; } /deep/.el-table__expan ...
- 学习框架/对象onbeforeunload事件
1.有没有发现在一些表单提交页面,当我们点击页面某个链接要离开表单提交页面时会弹出一个提示信息,如下: 那么,这是提示是怎么产生的呢?代码如下: window.onbeforeunload=funct ...
- 微信接口开发报错invalid credential, access_token is invalid or not latest hint
微信接口凭证access_token一定要全局管理 我们的查酒后台集成了微信公众平台的客服API接口,不用登录微信公众号的后台就可以直接给用户发送消息.最近,运营的同事反馈,通过微信查酒,后台无法直接 ...
- Nginx 日志记录post数据,并使用goaccess进行日志分析
nginx日志默认不会记录post数据 在nginx配置文件的http节 log_format 日志格式标识 [escape=json] 日志格式 比如:日志格式标识设置为main,添加escape= ...
- 搭建服务器上的GIT并实现自动同步到站点目录(www)
https://blog.csdn.net/baidu_30000217/article/details/51327289 前言:当我们想要实现几个小伙伴合作开发同一个项目,或者建立一个资源分享平台的 ...
- Python--day41--递归锁Rlock
1,递归锁Rlock:递归锁是为了解决死锁问题,且递归锁的特点是在同一个线程中可以被acquire()多次 多个acquire()在递归锁中不会阻塞,而互斥锁Lock就会阻塞 代码示例: from t ...
- Python--day40--datetime,socketserver,Threading模块分别是哪些模块的高层模块
- Spring Security原理篇(一) 启动原理
1.概述 spring security有参考的中文翻译文档https://springcloud.cc/spring-security-zhcn.html 在学习spring security的时候 ...
- linux scull 的设计
编写驱动的第一步是定义驱动将要提供给用户程序的能力(机制).因为我们的"设备"是计算 机内存的一部分, 我们可自由做我们想做的事情. 它可以是一个顺序的或者随机存取的设 备, 一个 ...