第四十章 POSIX条件变量
条件变量
- 当一个线程互斥地访问某个变量时,它可能发现在其它线程改变状态之前,它什么也做不了
- 例如一个线程访问队列时,发现队列为空,它只能等待,只到其它线程将一个节点添加到队列中。这种情况就需要用到条件变量
条件变量和互斥锁为什么要配合使用?
- 条件本身就是公共资源,多个线程同时方式时,必须使用互斥锁在临界区内对条件进行保护。
- 条件变量的作用是在等待某个条件达成时自身要进行睡眠或阻塞,避免忙等待带来的不必要消耗;当被唤醒时,会重新尝试加锁,如果锁成功,才进行之后的流程;否则解锁,继续阻塞
条件变量函数
pthread_cond_init
功能:
initialize condition variables
原型:
int pthread_cond_init(pthread_cond_t *restrict cond,
const pthread_condattr_t *restrict attr);
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
参数:
cond : 指向结构pthread_cond_t的指针
attr : 条件变量的属性结构的指针
返回值:
成功 : 0
失败 : 返回错误码
pthread_cond_destroy
功能:
destroy condition variables
原型:
int pthread_cond_destroy(pthread_cond_t *cond);
参数:
cond : 指向结构pthread_cond_t的指针
返回值:
成功 : 0
失败 : 返回错误码
pthread_cond_wait
功能:
wait on a condition
原型:
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
参数:
cond : 指向结构pthread_cond_t的指针
mutex : 互斥锁
返回值:
成功 : 0
失败 : 返回错误码
pthread_cond_signal
功能:
signal a condition
原型:
int pthread_cond_signal(pthread_cond_t *cond);
参数:
cond : 指向结构pthread_cond_t的指针
返回值:
成功 : 0
失败 : 返回错误码
pthread_cond_broadcast
功能:
signal a condition
原型:
broadcast a condition
参数:
cond : 指向结构pthread_cond_t的指针
返回值:
成功 : 0
失败 : 返回错误码
条件变量使用规范
等待条件代码
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);
使用条件变量解决生产者、消费者问题
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <semaphore.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
#define CONSUMERS_COUNT 2 //消费者线程的个数
#define PRODUCERS_COUNT 1 //生产者线程的个数
int nready = 0;
pthread_cond_t g_cond;
pthread_mutex_t g_mutex;
pthread_t g_thread[CONSUMERS_COUNT + PRODUCERS_COUNT]; //总线程数
void *consume(void *arg)
{
int num = (int)arg;
while (1)
{
pthread_mutex_lock(&g_mutex);
while(nready == 0)
{
printf("%d wait a condition...\n", num);
pthread_cond_wait(&g_cond, &g_mutex);
}
printf("%d end wait...\n", num);
printf("%d begin consume product...\n",num);
--nready;
printf("%d end consume product...\n",num);
pthread_mutex_unlock(&g_mutex);
sleep(1);
}
return NULL;
}
void *produce(void *arg)
{
int num = (int)arg;
while (1)
{
pthread_mutex_lock(&g_mutex);
printf("%d begin produce product...\n", num);
++nready;
printf("%d end produce product...\n", num);
pthread_cond_signal(&g_cond);
printf("%d singal ...\n",num);
pthread_mutex_unlock(&g_mutex);
sleep(1);
}
return NULL;
}
int main()
{
int i;
pthread_cond_init(&g_cond, NULL);
pthread_mutex_init(&g_mutex, NULL);
for (i = 0; i < CONSUMERS_COUNT; ++i)
{
pthread_create(&g_thread[i], NULL, consume, (void *)i);
}
sleep(1);
for (i = 0; i < PRODUCERS_COUNT; ++i)
{
pthread_create(&g_thread[CONSUMERS_COUNT + i], NULL, produce, (void *)i);
}
for (i = 0; i < CONSUMERS_COUNT + PRODUCERS_COUNT; ++i)
{
pthread_join(g_thread[i], NULL);
}
pthread_cond_destroy(&g_cond);
pthread_mutex_destroy(&g_mutex);
return 0;
}
pthread_cond_wait
- 对mutex进行解锁
- 等待条件,直到有线程向它发起通知
- 重新对mutex进行加锁操作
pthread_cond_signal
向等待的条件的线程发起通知,如果没有任何一个处于等待条件的状态,这个通知将被忽略
为什么要用while
- pthread_cond_wait会自动重启,就像这个信号没有发生过一样
- pthread_cond_wait可能会被虚假的唤醒,当被虚假唤醒后,需要重新判断条件
第四十章 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的最后一个相关知识----条件变量,言归正传. 下面用一个图来进一步描述条件变量的作用: 为什么呢? 这实际上可以解决生产者与消费者问题,而且对于缓冲区是无界的是一种比较理解的解决 ...
- linux网络编程-posix条件变量(40)
举一个列子来说明条件变量: 假设有两个线程同时访问全局变量n,初始化值是0, 一个线程进入临界区,进行互斥操作,线程当n大于0的时候才执行下面的操作,如果n不大于0,该线程就一直等待. 另外一个线程也 ...
- POSIX条件变量
条件变量: 当一个线程互斥的访问某个变量时,它可能发现其他线程改变状态之前,它什么都做不了例如:一个线程访问队列时,发现队列为空,它只能等待,直到其他线程将一个节点添加到队列中,这种情况就需要使用条件 ...
- Linux互斥锁、条件变量和信号量
Linux互斥锁.条件变量和信号量 来自http://kongweile.iteye.com/blog/1155490 http://www.cnblogs.com/qingxia/archive/ ...
- 进程间通信机制(管道、信号、共享内存/信号量/消息队列)、线程间通信机制(互斥锁、条件变量、posix匿名信号量)
注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料如<linux内核完全剖析>.<linux c 编程一站式学习>等,只是为了更好 ...
- 并发编程(一): POSIX 使用互斥量和条件变量实现生产者/消费者问题
boost的mutex,condition_variable非常好用.但是在Linux上,boost实际上做的是对pthread_mutex_t和pthread_cond_t的一系列的封装.因此通过对 ...
随机推荐
- WebGL简易教程(六):第一个三维示例(使用模型视图投影变换)
目录 1. 概述 2. 示例:绘制多个三角形 2.1. Triangle_MVPMatrix.html 2.2. Triangle_MVPMatrix.js 2.2.1. 数据加入Z值 2.2.2. ...
- 使用java的循环单向链表解决约瑟夫问题
什么是约瑟夫问题 据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定 ...
- C++——多文件结构和编译预处理命令
[toc] 一.多文件结构 1.一个工程可以划分为多个源文件 类声明文件(.h文件) 类实现文件(.cpp文件) 类的使用文件(main函数所在的.cpp文件) 2.利用工程来组合各个文件 //Poi ...
- 一个网站完整的SEO优化方案,方法,怎么做seo优化?
SEO优化主要分为站内优化,站外优化.如果非得说一套完整的SEO优化方案,那就是需要4名专业人员:前端人员,内容编辑,网络推广人员,和数据分析人员.那以下就详细介绍这四个岗位各自负责的工作有哪些: 一 ...
- 小程序webview调用微信扫一扫的“曲折”思路
自上一篇遇到webview中没有返回按钮之后,虽然跳出坑了.解决方案:<小程序webview跳转页面后没有返回按钮完美解决方案> 但是,小程序踩坑之路并没有结束.在公众号网页中通过配置AP ...
- Http协议Content-Length详解
前言 http协议是互联网中最重要的协议之一,虽然看上去很简单,但是实际中经常遇到问题,我们就已经遇到好几次了.有长连接相关的,有报文解析相关的.对http协议不能一知半解,必须透彻理解才行.本文通过 ...
- JPG和PNG特性分析及适用范围
个人博客: http://mcchen.club JPG的特性 ----有损压缩 1.支持摄影图像或写实图像的高级压缩,并且可利用压缩比例控制图像文件大小. 2.有损压缩会使图像数据质量下降,并且 ...
- 利用npm安装/删除/查看包信息
查看远程服务器上的包的版本信息 npm view webpack version //查看npm服务器上包webpack的最新版本 npm view webpack versions //查看服务器上 ...
- 基于STM32F429和HAL库的CAN收发例程
1.CAN协议介绍 CAN 是 Controller Area Network 的缩写(以下称为 CAN),是 ISO 国际标准化的串行通信协议.在当前的汽车产业中,出于对安全性.舒适性.方便性.低公 ...
- C语言I作业004
这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 作业 我在这个课程的目标是 掌握使用for循环语句实现指定次数的循环程序设计 这个作业在那个具体方面帮助我实现目标 pta运用for循环语 ...