Linux线程同步:条件变量
条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足,它常和互斥锁一起使用。使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化。一旦其它的某个线程改变了条件变量,它将通知相应的条件变量唤醒一个或多个正被此条件变量阻塞的线程。这些线程将重新锁定互斥锁并重新测试条件是否满足。一般说来,条件变量被用来进行线承间的同步。
1、条件变量的结构为 pthread_cond_t (相当于windows中的事件的作用)
2、条件变量的初始化
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);
其中 cond 是一个指向结构 pthread_cond_t 的指针,cond_attr 是一个指向结构 pthread_condattr_t 的指针。结构 pthread_condattr_t 是条件变量的属性结构,和互斥锁一样我们可以用它来设置条件变量是进程内可用还是进程间可用,默认值是 PTHREAD_ PROCESS_PRIVATE,即此条件变量被同一进程内的各个线程使用。注意初始化条件变量只有未被使用时才能重新初始化或被释放。
3、条件变量的释放
释放一个条件变量的函数为
int pthread_cond_destroy(pthread_cond_t *cond);
4、条件变量的等待
(1)函数 pthread_cond_wait() 使线程阻塞在一个条件变量上。它的函数原型为:
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
线程解开mutex指向的锁并被条件变量cond阻塞。线程可以被函数 pthread_cond_signal 和函数 pthread_cond_broadcast 唤醒,但是要注意的是,条件变量只是起阻塞和唤醒线程的作用,具体的判断条件还需用户给出,例如一个变量是否为0等等,这一点我们从后面的例子中可以看到。线程被唤醒后,它将重新检查判断条件是否满足,如果还不满足,一般说来线程应该仍阻塞在这里,被等待被下一次唤醒。这个过程一般用 while语句 实现。
(2)另一个用来阻塞线程的函数是 pthread_cond_timedwait(),它的原型为:
int pthread_cond_timewait(pthread_cond_t *cond, pthread_mutex *mutex, const timespec *abstime);
它比函数pthread_cond_wait()多了一个时间参数,经历abstime段时间后,即使条件变量不满足,阻塞也被解除。
5、条件变量的解除改变
函数 pthread_cond_signal() 的原型为:
int pthread_cond_signal(pthread_cond_t *cond);
它用来释放被阻塞在条件变量cond上的一个线程。多个线程阻塞在此条件变量上时,哪一个线程被唤醒是由线程的调度策略 所决定的。要注意的是,必须用保护条件变量的互斥锁来保护这个函数,否则条件满足信号又可能在测试条件和调用 pthread_cond_wait 函数之间被发出,从而造成无限制的等待。
6、下面是使用函数 pthread_cond_wait() 和函数 pthread_cond_signal() 的一个简单的例子。
count值为 0 时,decrement函数在 pthread_cond_wait 处被阻塞,并打开互斥锁 count_lock。此时,当调用到函数 increment_count 时,pthread_cond_signal() 函数改变条件变量,告知decrement_count() 停止阻塞。
# 以下是 伪代码 #
pthread_mutex_t count_lock;
pthread_cond_t count_nonzero;
unsigned count; decrement_count()
{
pthread_mutex_lock(&count_lock);
while (count == 0)
{
pthread_cond_wait(&count_nonzero, &count_lock);
}
count = count -1;
pthread_mutex_unlock(&count_lock);
} increment_count()
{
pthread_mutex_lock(&count_lock);
if (count == 0)
{
pthread_cond_signal(&count_nonzero);
}
count = count + 1;
pthread_mutex_unlock(&count_lock);
}
count 值为 0 时,decrement 函数在 pthread_cond_wait 处被阻塞,并打开互斥锁 count_lock。此时,当调用到函数 increment_count 时,pthread_cond_signal() 函数改变条件变量,告知decrement_count() 停止阻塞。
参考:
http://www.cnblogs.com/feisky/archive/2010/03/08/1680950.html
http://blog.csdn.net/dai_weitao/article/details/1754964
Linux线程同步:条件变量的更多相关文章
- Linux线程同步——条件变量
互斥锁是用来给资源上锁的,而条件变量是用来等待而不是用来上锁的. 条件变量用来自动阻塞一个线程,直到某特殊情况发生为止. 通常条件变量和互斥锁同时使用. 和条件变量使用有关的几个重要函数: int p ...
- linux Posix线程同步(条件变量) 实例
条件变量:与互斥量一起使用,暂时申请不到某资源时进入条件阻塞等待,当资源具备时线程恢复运行 应用场合:生产线程不断的生产资源,并通知产生资源的条件,消费线程在没有资源情况下进入条件等待,一直等到条件信 ...
- pThreads线程(三) 线程同步--条件变量
条件变量(Condition Variables) 参考资料:http://game-lab.org/posts/posix-thread-cn/#5.1 条件变量是什么? 条件变量为我们提供了另一种 ...
- linux线程同步(2)-条件变量
一.概述 上一篇,介绍了互斥量.条件变量与互斥量不同,互斥量是防止多线程同时访问共享的互斥变量来保 ...
- 【转】 Linux 线程同步的三种方法
线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点.linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 一.互斥锁(mutex) 通过锁机制实现线程间的 ...
- Java线程:条件变量、原子量、线程池等
一.条件变量 条件变量实现了java.util.concurrent.locks.Condition接口,条件变量的实例化就是通过一个Lock对象上调用newCondition()方法获得的,这样条件 ...
- linux 线程同步(二)
信号量 信号量是相互排斥锁的升级版把相互排斥锁中1变成了n.举个简单的样例:如果如今有10个人,有一部手机.这10个人都竞争来使用手机打电话这就是相互排斥锁.对于信号量,如今可能是有4部手机,这10个 ...
- Linux 线程同步的三种方法(互斥锁、条件变量、信号量)
互斥锁 #include <cstdio> #include <cstdlib> #include <unistd.h> #include <pthread. ...
- linux多线程-互斥&条件变量与同步
多线程代码问题描述 我们都知道,进程是操作系统对运行程序资源分配的基本单位,而线程是程序逻辑,调用的基本单位.在多线程的程序中,多个线程共享临界区资源,那么就会有问题: 比如 #include < ...
随机推荐
- 【2016-10-20】【坚持学习】【Day10】【反射2】
Type类的属性: Name 数据类型名 FullName 数据类型的完全限定名(包括命名空间名) Namespace 定义数据类型的命名空间名 ...
- js/jquery/html前端开发常用到代码片段
1.IE条件注释 条件注释简介 IE中的条件注释(Conditional comments)对IE的版本和IE非IE有优秀的区分能力,是WEB设计中常用的hack方法.条件注释只能用于IE5以上,IE ...
- UVA 10564 Paths through the Hourglass[DP 打印]
UVA - 10564 Paths through the Hourglass 题意: 要求从第一层走到最下面一层,只能往左下或右下走 问有多少条路径之和刚好等于S? 如果有的话,输出字典序最小的路径 ...
- selenium自动化-java-封装断言
封装的断言. 1 package com.baidu.www; import org.testng.Assert; /* * 封装断言 */ public class assertion { stat ...
- button
- AngularJS 之 Factory vs Service vs Provider【转】
英文原文:AngularJS: Factory vs Service vs Provider 当你初试 Angular 时,很自然地就会往 controller 和 scope 里堆满不必要的逻辑.一 ...
- WEB安全:XSS漏洞与SQL注入漏洞介绍及解决方案
对web安全方面的知识非常薄弱,这篇文章把Xss跨站攻击和sql注入的相关知识整理了下,希望大家多多提意见. 对于防止sql注入发生,我只用过简单拼接字符串的注入及参数化查询,可以说没什么好经验,为避 ...
- CSS基本知识3-CSS盒模型
box-sizing: content-box|border-box|inherit; 值 描述 content-box 这是由 CSS2.1 规定的宽度高度行为. 宽度和高度分别应用到元素的内容框. ...
- 一个简单的Linq to TreeNode
最近两天写单元测试,碰到需要验证一个树是否是期望的,但是树这个结构要验证起来还真是有点烦... 我的树大概是这样的: class TreeNode<T> { ]; public TreeN ...
- SVN合并代码
分之合并主干代码, 修改冲突后提交, 更新本地代码, 主干合并分之,