POSIX条件变量
条件变量:
当一个线程互斥的访问某个变量时,它可能发现其他线程改变状态之前,它什么都做不了
例如:一个线程访问队列时,发现队列为空,它只能等待,直到其他线程将一个节点添加到队列中,这种情况就需要使用条件变量。
线程A: 线程B:
改变n
int n=0 进入临界区
进入临界区
更改 n>0
等待 n>0(该线程进入临界区其他的线程无法运行) 通知等待线程
操作n 退出临界区
退出临界区
注意:当一个线程进入临界区,等待n>0,其余的线程无法获取互斥量(同一个互斥量)进入临界区修改n,那么线程A就会一直等待。
就会出现死锁,所以我们引入了条件变量。条件变量要跟互斥量配合使用,一是因为多个线程都可以访问条件n>0;而是因为一个线程
对互斥量加锁,其他线程就无法获得互斥量修改n.所以条件变量一开始先解锁,那么线程就可以获得互斥量,修改n.也可以等待条件。
条件变量使用规范
等待条件代码:
pthread_mutex_lock(&mutex);
while(条件为假)
pthread_cond_wait(cond,mutex);
修改条件
pthread_mutex_unlock(&mutex);
给条件发送信号代码:
pthread_mutex_lock(&mutex);
设置条件为真
pthread_cond_signal(cond);
pthread_mutex_unlock(&mutex);
通知条件成立
int pthread_cond_signal(pthread_cond_t *cond);
等待条件成立
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
while(1)
{
pthread_mutex_lock(&g_mutex);
//为何使用while而不是if
//被信号打断的话,一种pthread_cond_wait重启,就行没有发生一样,或者pthread_cond_wait可能被虚假唤醒,所以要用while再次判断条件。
while(nready==0)
{
pthread_cond_wait(&g_cond,&g_mutex);
}
--nready;
pthread_mutex_unlock(&g_mutex);
}
pthread_cond_wait(原语)内部进行的操作:
一、对g_mutex进行解锁(其他消费者线程可以进行等待,生产者线程也可以改变条件)
二、等待条件,直到其他线程向它发起通知
三、返回的时候对互斥量重新加锁
while(1)
{
pthread_mutex_lock(&g_mutex);
nready++;
if(nready>0)
pthread_cond_signal(&g_cond);//条件满足,发起通知
pthread_mutex_unlock(&g_mutex);
}
pthread_cond_signal
向第一个等待条件的线程发起通知,如果没有任何一个线程处于等待条件的状态,这个通知将被忽略
pthread_cond_broadcast
向所有的等待线程发起通知
用条件变量解决生产者、消费者问题(缓冲区无界,假定仓库无限大)
1 #include<unistd.h>
2 #include<sys/types.h>
3 #include<fcntl.h>
4 #include<sys/stat.h>
5 #include<stdlib.h>
6 #include<stdio.h>
7 #include<errno.h>
8 #include <semaphore.h>
9 #include<pthread.h>
10 #define ERR_EXIT(m)\
11 do\
12 {\
13 perror(m);\
14 exit(EXIT_FAILURE);\
15 }while(0)
16 #define CONSUMERS_COUNT 2
17 #define PRODUCERS_COUNT 4
18
19 unsigned short in=0;
20 unsigned short out=0;
21 unsigned short produce_id=0;//当前正在消费的产品ID
22 unsigned short consume_id=0;//当前正在消费的产品ID
23
24 pthread_cond_t g_cond;
25 pthread_mutex_t g_mutex;
26 pthread_t g_thread[CONSUMERS_COUNT+PRODUCERS_COUNT ];
27
28 //消费者线程
29 int nready=0;//缓冲区没有产品
30 void* consume(void*arg)
31 {
32 int num=(int)arg;//线程编号
33
34 while(1)
35 {
36 pthread_mutex_lock(&g_mutex);
37 //当条件不成立,就一直等待。
38 while(nready==0)
39 {
40 printf("%d begin wait a condition...\n",num);
41 //跟互斥锁配合使用,先解锁,以便其他线程进入临界区修改条件,防止死锁。
42 pthread_cond_wait(&g_cond,&g_mutex);//在nready==0上等待。
43 //再加锁
44 }
45 //条件改变了
46 printf("%d end wait a condition...\n",num);
47 printf("%d begin consume product...\n",num);
48 --nready;//消费产品
49 pthread_mutex_unlock(&g_mutex);
50 sleep(1);
51 }
52 return NULL;
53 }
54 //生产者线程
55 void* produce(void*arg)
56 {
57 int num=(int)arg;
58
59 while(1)
60 {
61 pthread_mutex_lock(&g_mutex);
62 printf("%d begin produce product...\n",num);
63 nready++;//直接开始生产产品。
64 printf("%d end produce product...\n",num);
65 //条件成立,通知等待线程
66 pthread_cond_signal(&g_cond);
67 printf("%d signal \n",num);//某个线程发起通知
68 pthread_mutex_unlock(&g_mutex);
69 sleep(1);
70 }
71 return NULL;
72 }
73 int main(void)
74 {
75 int i;
76 //初始化互斥量和条件变量
77 pthread_mutex_init(&g_mutex,NULL);
78 pthread_cond_init(&g_cond,NULL);
79 //创建消费者线程
80 for(i=0;i<CONSUMERS_COUNT;i++)
81 {
82 pthread_create(&g_thread[i],NULL,consume,(void*)i);//产生了段错误.我们传递的是值,所以int num=(int)arg 而不是int num=*(int*)arg
83 }
84
85 sleep(1);//以便消费者进入等待
86 //创建生产者线程
87 for(i=0;i<PRODUCERS_COUNT;i++)
88 {
89 pthread_create(&g_thread[i+CONSUMERS_COUNT],NULL,produce,(void*)i);
90 }
91 //等待线程退出
92 for(i=0;i<CONSUMERS_COUNT+PRODUCERS_COUNT;i++)
93 {
94 pthread_join(g_thread[i],NULL);
95 }
96
97 pthread_cond_destroy(&g_cond);
98 pthread_mutex_destroy(&g_mutex);
99 return 0;
100 }
POSIX条件变量的更多相关文章
- Linux多线程实践(8) --Posix条件变量解决生产者消费者问题
Posix条件变量 int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr); int pthread_co ...
- posix 条件变量与互斥锁 示例生产者--消费者问题
一.posix 条件变量 一种线程间同步的情形:线程A需要等某个条件成立才能继续往下执行,现在这个条件不成立,线程A就阻塞等待,而线程B在执行过程中使这个条件成立了,就唤醒线程A继续执行. 在pthr ...
- Linux多线程实践(六)使用Posix条件变量解决生产者消费者问题
前面的一片文章我们已经讲过使用信号量解决生产者消费者问题.那么什么情况下我们须要引入条件变量呢? 这里借用 http://www.cnblogs.com/ngnetboy/p/3521547.htm ...
- linux网络编程之posix条件变量
今天来学习posix的最后一个相关知识----条件变量,言归正传. 下面用一个图来进一步描述条件变量的作用: 为什么呢? 这实际上可以解决生产者与消费者问题,而且对于缓冲区是无界的是一种比较理解的解决 ...
- 第四十章 POSIX条件变量
条件变量 当一个线程互斥地访问某个变量时,它可能发现在其它线程改变状态之前,它什么也做不了 例如一个线程访问队列时,发现队列为空,它只能等待,只到其它线程将一个节点添加到队列中.这种情况就需要用到条件 ...
- linux网络编程-posix条件变量(40)
举一个列子来说明条件变量: 假设有两个线程同时访问全局变量n,初始化值是0, 一个线程进入临界区,进行互斥操作,线程当n大于0的时候才执行下面的操作,如果n不大于0,该线程就一直等待. 另外一个线程也 ...
- Linux互斥锁、条件变量和信号量
Linux互斥锁.条件变量和信号量 来自http://kongweile.iteye.com/blog/1155490 http://www.cnblogs.com/qingxia/archive/ ...
- 并发编程(一): POSIX 使用互斥量和条件变量实现生产者/消费者问题
boost的mutex,condition_variable非常好用.但是在Linux上,boost实际上做的是对pthread_mutex_t和pthread_cond_t的一系列的封装.因此通过对 ...
- 进程间通信机制(管道、信号、共享内存/信号量/消息队列)、线程间通信机制(互斥锁、条件变量、posix匿名信号量)
注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料如<linux内核完全剖析>.<linux c 编程一站式学习>等,只是为了更好 ...
随机推荐
- 多测师讲解自动化--rf关键字--断言(下)_高级讲师肖sir
断言: 1.1Page Should Contain Maximize Browser Window sleep 2 Comment Page Should Contain hao123 #断言当前页 ...
- element中过滤器filters的使用(开发小记)
之前在开发过程中遇到这么一个问题,一串数据需要在el-table中展示,其中含有金额字段,需要将其转换成标准数据格式,即三位一个逗号间隔. 今年刚毕业就上手项目了,第一次接触的Vue,开发经验少,也忘 ...
- day51 Pyhton 前端02
内容回顾: 1.h1~h6:加粗,数字越大级别越小,自动换行 2.br:换行;hr:分割线; (特殊符号,空格) 3.p:与前边和后边内容之间有间距 4.a标签的href:本地文件连接;网络连接;锚链 ...
- docker下安装kafka和kafka-manager
1.下载镜像 这里使用了wurstmeister/kafka和wurstmeister/zookeeper这两个版本的镜像 docker pull wurstmeister/zookeeper doc ...
- spring boot:thymeleaf模板中insert/include/replace三种引用fragment方式的区别(spring boot 2.3.3)
一,thymeleaf模板中insert/include/replace三种引用fragment方式的区别 insert: 把整个fragment(包括fragment的节点tag)插入到当前节点内部 ...
- ImageMagick实现图片加水印(ImageMagick6.9.10)
一,ImageMagick的安装 请参见: https://www.cnblogs.com/architectforest/p/12807514.html 说明:刘宏缔的架构森林是一个专注架构的博客, ...
- apache的ab压力测试介绍
1.ab命令原理 Apache的ab命令模拟多线程并发请求,测试服务器负载压力,也可以测试nginx.lighthttp.IIS等其它Web服务器的压力. ab命令对发出负载的计算机要求很低,既不会占 ...
- 使用原生js模拟jQuery选择器,实现new方法,兼容ie5
// 考虑到兼容ie5,未使用es6语法 /* 使用方法: 在<head>标签中(需使用ready方法): <script src="./jQuery2.js"& ...
- <article>
今天介绍的是html中<article>标签的用法,如果有兴趣的朋友可以看一下! <article> 标签规定独立的自包含内容. 一篇文章应有其自身的意义,应该有可能独立于站点 ...
- Python列表的增删改查
列表的增: li = ['libai','sushi','dufu','sushi',"白居易"] 第一种: append():向列表末尾追加元素 li.append('diaoc ...