条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足,它常和互斥锁一起使用。使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化。一旦其它的某个线程改变了条件变量,它将通知相应的条件变量唤醒一个或多个正被此条件变量阻塞的线程。这些线程将重新锁定互斥锁并重新测试条件是否满足。一般说来,条件变量被用来进行线承间的同步。

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线程同步:条件变量的更多相关文章

  1. Linux线程同步——条件变量

    互斥锁是用来给资源上锁的,而条件变量是用来等待而不是用来上锁的. 条件变量用来自动阻塞一个线程,直到某特殊情况发生为止. 通常条件变量和互斥锁同时使用. 和条件变量使用有关的几个重要函数: int p ...

  2. linux Posix线程同步(条件变量) 实例

    条件变量:与互斥量一起使用,暂时申请不到某资源时进入条件阻塞等待,当资源具备时线程恢复运行 应用场合:生产线程不断的生产资源,并通知产生资源的条件,消费线程在没有资源情况下进入条件等待,一直等到条件信 ...

  3. pThreads线程(三) 线程同步--条件变量

    条件变量(Condition Variables) 参考资料:http://game-lab.org/posts/posix-thread-cn/#5.1 条件变量是什么? 条件变量为我们提供了另一种 ...

  4. linux线程同步(2)-条件变量

    一.概述                                                    上一篇,介绍了互斥量.条件变量与互斥量不同,互斥量是防止多线程同时访问共享的互斥变量来保 ...

  5. 【转】 Linux 线程同步的三种方法

    线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点.linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 一.互斥锁(mutex) 通过锁机制实现线程间的 ...

  6. Java线程:条件变量、原子量、线程池等

    一.条件变量 条件变量实现了java.util.concurrent.locks.Condition接口,条件变量的实例化就是通过一个Lock对象上调用newCondition()方法获得的,这样条件 ...

  7. linux 线程同步(二)

    信号量 信号量是相互排斥锁的升级版把相互排斥锁中1变成了n.举个简单的样例:如果如今有10个人,有一部手机.这10个人都竞争来使用手机打电话这就是相互排斥锁.对于信号量,如今可能是有4部手机,这10个 ...

  8. Linux 线程同步的三种方法(互斥锁、条件变量、信号量)

    互斥锁 #include <cstdio> #include <cstdlib> #include <unistd.h> #include <pthread. ...

  9. linux多线程-互斥&条件变量与同步

    多线程代码问题描述 我们都知道,进程是操作系统对运行程序资源分配的基本单位,而线程是程序逻辑,调用的基本单位.在多线程的程序中,多个线程共享临界区资源,那么就会有问题: 比如 #include < ...

随机推荐

  1. 模-数(A/D)转换器

    一.A/D转换的基本原理 在一系列选定的瞬间对模拟信号进行取样,然后再将这些取样值转换成输出的数字量,并按一定的编码形式给出转换结果. 整个A/D转换过程大致可分为取样.量化.编码三个过程.二.取样- ...

  2. http、tcp、udp、OAUTH2.0网络协议区别

                    一.先来一个讲TCP.UDP和HTTP关系的 1.TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层. 在网络层有IP协议.ICMP协议.ARP协议.RAR ...

  3. 《Java EE 开发技术与案例教程》 这是一本好书啊:简洁精辟(相见恨晚)

    第一章:Java EE 概述 1.get:JPA:Java Persistence API, 数据持久化API: JPA是一种ORM规范,它的实现实例:Hibernate.mybatis 2.Web ...

  4. [转]Extjs combo数据绑定与获取

    原文地址:http://www.cnblogs.com/loveme123/archive/2012/05/10/2494466.html 1. 配置combo: {                  ...

  5. 使用CocoaPods开发并打包静态库

    Cocoapods作为OS X和iOS开发平台的类库管理工具,已经非常完善和强大.通常我们用pod来管理第三方开源类库,但我们也极有可能会开发一个用pod管理依赖关系的静态类库给其他人使用,而又不愿意 ...

  6. 解决 Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in

    转载 php 5个版本,5.2.5.3.5.4.5.5,怕跟不上时代,新的服务器直接上5.5,但是程序出现如下错误:Deprecated: mysql_connect(): The mysql ext ...

  7. IE下get传中文乱码的问题完美解决方案

    前几天做项目的时候遇到需要在easyui的combobox的url中以get的方式传中文,出现乱码. $('#cc').combobox({ url : 'xxxAction.action?para= ...

  8. Java,来源于大神

    也许你学习了那么久的Java了,但如果有人问你什么是JavaEE?你会怎么回答他呢?在此我来谈谈关于JavaEE的相关技术.(仅是个人见解) 在谈JavaEE时,我们首先来了解一下Java平台.目前, ...

  9. fedora22命令useradd,groupadd等命令不能自动补全

    sudo ls -l /sbin/useradd 发现登陆账户没有读权限 修改为其他账户为读权限即可

  10. microsoft docx document operation with Java POI library

    microsoft docx document operation with Java POI library combine multiple docx document into one docu ...