pthread之条件变量pthread_cond_t
pthread之条件变量pthread_cond_t
条件变量 条件变量是利用线程间共享的全局变量进行同步的一种机制, 主要包括两个动作: 一个线程等待"条件变量的条件成立"而挂起; 另一个线程使"条件成立"(给出条件成立信号). 为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。
1. 创建和注销 条件变量和互斥锁一样,都有静态和动态两种创建方式, 静态方式使用PTHREAD_COND_INITIALIZER常量, 如下: pthread_cond_t cond = PTHREAD_COND_INITIALIZER
动态方式调用pthread_cond_init()函数,API定义如下: int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);
尽管POSIX标准中为条件变量定义了属性,但在LinuxThreads中没有实现, 因此cond_attr值通常为NULL,且被忽略.
注销一个条件变量需要调用pthread_cond_destroy(), 只有在没有线程在该条件变量上等待的时候才能注销这个条件变量,否则返回EBUSY。 因为Linux实现的条件变量没有分配什么资源,所以注销动作只包括检查是否有等待线程。 API定义如下: int pthread_cond_destroy(pthread_cond_t *cond);
2. 等待和激发
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
等待条件有两种方式: 无条件等待 pthread_cond_wait(); 计时等待 pthread_cond_timedwait(); 其中计时等待方式如果在给定时刻前条件没有满足,则返回ETIMEOUT,结束等待. 其中abstime以与time()系统调用相同意义的绝对时间形式出现,0表示格林尼治时间1970年1月1日0时0分0秒。
无论哪种等待方式,都必须和一个互斥锁配合, 以防止多个线程同时请求pthread_cond_wait()(或pthread_cond_timedwait(),下同)的竞争条件(Race Condition).
mutex互斥锁必须是普通锁(PTHREAD_MUTEX_TIMED_NP)或者适应锁(PTHREAD_MUTEX_ADAPTIVE_NP), 且在调用pthread_cond_wait()前必须由本线程加锁(pthread_mutex_lock()), 而在更新条件等待队列以前,mutex保持锁定状态,并在线程挂起进入等待前解锁. 在条件满足从而离开pthread_cond_wait()之前,mutex将被重新加锁,以与进入pthread_cond_wait()前的加锁动作对应。
激发条件有两种形式:
1.pthread_cond_signal();
激活一个等待该条件的线程,存在多个等待线程时按入队顺序激活其中一个;
2.pthread_cond_broadcast();
激活所有等待线程。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;struct node
{
int n_number;
struct node *n_next;
} *head = NULL;static void cleanup_handler(void *arg)
{
printf("Cleanup handler of second thread.\n");
free(arg);
(void)pthread_mutex_unlock(&mtx);
}static void *thread_func(void *arg)
{
struct node *p = NULL;pthread_cleanup_push(cleanup_handler, p);
while (1)
{
pthread_mutex_lock(&mtx); //这个mutex主要是用来保证pthread_cond_wait的并发性
while (head == NULL)
{
/*
* 这个while要特别说明一下,
* 单个pthread_cond_wait功能很完善,为何这里要有一个while (head == NULL)呢?
* 因为pthread_cond_wait里的线程可能会被意外唤醒,如果这个时候head != NULL,则不是我们想要的情况。
* 这个时候,应该让线程继续进入pthread_cond_wait
*//*
* pthread_cond_wait会先解除之前的pthread_mutex_lock锁定的mtx,
* 然后阻塞在等待对列里休眠,
* 直到再次被唤醒(大多数情况下是等待的条件成立而被唤醒,唤醒后,该线程会先锁定pthread_mutex_lock(&mtx);
* 再读取资源;
* 这个流程可以表述为:block-->unlock-->wait() return-->lock.
*/
pthread_cond_wait(&cond, &mtx);
}p = head;
head = head->n_next;
printf("Got %d from front of queue\n", p->n_number);free(p);
pthread_mutex_unlock(&mtx); //临界区数据操作完毕,释放互斥锁
}pthread_cleanup_pop(0);
return 0;
}int main(void)
{
pthread_t tid;
int i;
struct node *p;/*
* 子线程会一直等待资源,类似生产者和消费者,
* 但是这里的消费者可以是多个消费者,而不仅仅支持普通的单个消费者;
* 这个模型虽然简单,但是很强大
*/
pthread_create(&tid, NULL, thread_func, NULL); for (i = 0; i < 10; i++)
{
p = malloc(sizeof(struct node));
p->n_number = i;pthread_mutex_lock(&mtx); //需要操作head这个临界资源,先加锁,p->n_next = head;
head = p;pthread_cond_signal(&cond);
pthread_mutex_unlock(&mtx); //解锁sleep(1);
}printf("thread 1 wanna end the line.So cancel thread 2./n");/*
* 关于pthread_cancel, 有一点额外的说明,
* 它是从外部终止子线程,子线程会在最近的取消点,退出线程;
* 而在我们的代码里,最近的取消点肯定就是pthread_cond_wait()了。
* 关于取消点的信息,有兴趣可以google,这里不多说了
*/
pthread_cancel(tid);
pthread_join(tid, NULL);printf("All done -- exiting/n");
return 0;
}
转自: https://www.cnblogs.com/lemon-tree/p/5124153.html
pthread之条件变量pthread_cond_t相关推荐
- Linux多线程开发-线程同步-条件变量pthread_cond_t
1.条件变量的概念 一个线程A的执行需要另一个线程B来唤醒,否则A挂起等待.线程B可以产生线程A继续执行的信号.条件变量常用在共享数据状态变化的场景中,例如:生产则和消费者问题.POSIX线程库提供了 ...
- linux C语言多线程库pthread中条件变量的正确用法逐步详解
linux C语言多线程库pthread中条件变量的正确用法: 了解pthread常用多线程API和pthread互斥锁,但是对条件变量完全不知道或者不完全了解的人群. 关于条件变量的典型应用,可以参 ...
- Linux操作系统下的多线程编程详细解析----条件变量pthread_cond_t那些事儿
推荐两个博文: http://www.cnblogs.com/Creator/archive/2012/04/18/2455584.html http://blog.csdn.net/sunboy_2 ...
- POSIX多线程编程-条件变量pthread_cond_t
条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足,它常和互斥锁一起使用.使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化.一旦其它 ...
- 条件变量pthread_cond_t怎么用
LINUX系统编程这一快的知识,如果不经常使用的话,可能也会忘记,在项目中,可以代码可以看懂,但是自己亲自写的话,可能还是要翻一下<Linux 环境高级编程>这本书比较好,下面就简单 ...
- phtread条件变量pthread_cond_t初始化方式
1.静态方式 初始化方法: int x,y; pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREA ...
- [C/C++]_[初级]_[ 线程pthread学习之互斥锁和条件变量的应用 ]
一.互斥锁 互斥锁,是一种信号量,常用来防止两个进程或线程在同一时刻访问相同的共享资源. 需要的头文件:pthread.h 互斥锁标识符:pthread_mutex_t (1)互斥锁初始化: 函数原型 ...
- 【C++】多线程与条件变量【三】
文章目录 1 条件变量是什么? 实例1: 2 条件变量本质? 3 引入条件变量的原因? 实例2: 实例3: 实例4: 4 如何使用条件变量? 4.1 std::condition_variable 实 ...
- c++ linux 线程等待与唤醒_Linux线程同步(互斥量、信号量、条件变量、生产消费者模型)...
为什么要线程同步? 线程间有很多共享资源,都对一个共享数据读写操作,线程操作共享资源的先后顺序不确定,可能会造成数据的冲突 看一个例子 两个线程屏行对全局变量count++ (采用一个val值作为中间 ...
- 3线程同步:条件变量
1条件变量 条件变量给多个线程提供了一个汇合的场所. 依赖的头文件 #include<pthread.h> 函数声明 定义分配条件变量 pthread_cond_t cond =PTHRE ...
最新文章
- 【项目管理】Project使用
- 帮我看看这点破事 EVENT
- 串口之GetCommTimeouts、SetCommTimeouts函数详解
- pytorch 指定卡1_在pytorch中指定显卡
- java 消费者模式 多线程_[Java并发-24-并发设计模式] 生产者-消费者模式,并发提高效率...
- 力扣111. 二叉树的最小深度(JavaScript)
- SAP License:SAP低值易耗品管理
- C盘pagefile.sys不可删除,解决磁盘占用太满的问题
- 黑白染色——封锁阳光大学
- 数据结构C#版笔记--啥夫曼树(Huffman Tree)与啥夫曼编码(Huffman Encoding)
- ubuntu SecureCRT 下载并破解
- 如何搭建一个简单的QQ机器人(基于mirai)
- gvim【一】【安装和基本使用】
- excel文件转换成PDF格式
- LU分解、矩阵求逆与解线性方程组(matlab代码)
- 基于vue 2.x的移动端网页弹窗插件wc-messagebox(支持Alert,Confirm,Toast,Loading)
- 经典再读 | 认知控制和失匹配对N2成分的影响
- postman+newman
- 毕业3个月,我当上了部门主管
- JZOJ-senior-5952. 【NOIP2018模拟11.5A组】凯旋而归
热门文章
- 河南省邓州市计算机学校,2019年邓州市职业技术学校招生简章及招生专业
- ubuntu下怎样安装星际译王stardict和下载本地词典
- windows10强制删除文件_Windows10 初装必设置
- java script幻灯片效果,JS实现图片幻灯片效果代码实例
- android工厂测试开发,Android开机启动工程测试APK功能开发
- hdoj2602 0/1背包 动态规划 模版题( Java版)
- 用Delphi编写的一个上网助手
- 软件以人为本5 - 敏捷3 - 拯救每日立会2
- HttpClient4.X发送Get请求的url参数拼接
- matlab中gui选择一个文件,matlabgui中定义函数