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

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. 洛谷P1341 无序字母对[无向图欧拉路]

    题目描述 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现. 输入输出格式 输入格式: 第一行输入一 ...

  2. 解决 uuid.h找不到的问题

    http://blog.csdn.net/commshare/article/details/40835407

  3. BZOJ 4548 小奇的糖果

    Description 有 \(N\) 个彩色糖果在平面上.小奇想在平面上取一条水平的线段,并拾起它上方或下方的所有糖果.求出最多能够拾起多少糖果,使得获得的糖果并不包含所有的颜色. Input 包含 ...

  4. Mac--10.8.3下使用apache2方法

    在终端使用 sudo apachectl start  => 启动apache2 sudo apchectl stop => 停止 sudo apchectl restart => ...

  5. discuz论坛插件设计学习培训视频全套教程

    discuz模板跟插件开发的教程比较少,特搜集给大家学习插件做的好,在dsicuz应用中心出 售也是可以卖不少的呢 教程目录:第1章  本章的标题第1节Discuz! X 产品安装与配置第2节模板风格 ...

  6. 你一无所知的CSS

    也许标题有点夸大了.虽然不能完全保证大家都不知道这些,但是这也算是一个好机会检测下你是否知道或使用过下面的内容. Selectors Root :root { }  使用root可以让你在DOM中选择 ...

  7. .Net配置中心-简介

    系统简介 最近做了一个.Net配置中心,本质就是将原本放在各个站点下AppSettings中的配置统一管理,可以实现一次更改,自动更新,这里提供了两个版本, 一个是心跳版,一个是zookeeper版. ...

  8. MySql分页算法

    PERCONA PERFORMANCE CONFERENCE 2009上,来自雅虎的几位工程师带来了一篇"Efficient Pagination Using MySQL"的报告, ...

  9. 分享我的开源项目-springmore

    之前有在博客园分享过springmore,不知道是什么原因,被管理员移除首页 在此郑重声明,这是我个人的开源项目,东西不多,也不存在打广告,也没有什么利益可图 完全是出于分享的目的,望博客园管理员予以 ...

  10. 教你一招:Win10系统如何正确卸载edge浏览器?

    Edge浏览器作为Win10系统默认浏览器,尽管我们将其他浏览器设置为默认程序,但是有时候还是会自动弹出,非常的不爽,但是在控制面板中却又找不到卸载“Edge”浏览器的选项.下面小编就教大家卸载“Ed ...