条件变量主要用于实现线程之间的协作关系。

pthread_cond_t常用的操作有:

int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_destroy(pthread_cond_t *cond);

我先将Condition类的声明放在这里:

#ifndef CONDITION_H_
#define CONDITION_H_ #include "NonCopyable.h"
#include <pthread.h> class MutexLock; class Condition : NonCopyable
{
public:
Condition(MutexLock &mutex);
~Condition(); void wait();
void notify();
void notifyAll(); private:
pthread_cond_t cond_;
MutexLock &mutex_;
}; #endif //CONDITION_H_

这里注意几点:

1.wait必须在加锁的条件下调用。

2.notify一次唤醒一个线程,通常用来通知资源可用

3.notifyAll一次通知多个线程,通常用来通知状态的改变。滥用broadcast会导致“惊群”问题。

使用wait必须采用while判断,原因在于:

a) 如果采用if,最多判断一次。

b) 线程A等待数据,阻塞在full上,那么当另一个线程放入产品时,通知A去拿数据,此时另一个线程B抢到锁,直接进入临界区,取走资源。A重新抢到锁,(因为采用的是if,所以不会判断第二次)进去临界区时,已经没有资源。

c)防止broadcast的干扰,如果获得一个资源,使用broadcast会唤醒所有等待的线程,那么多个线程被唤醒,但最终只有一个能拿到资源,这就是所谓的“惊群效应”。

cpp代码实现如下:

#include "Condition.h"
#include "MutexLock.h"
#include <assert.h> Condition::Condition(MutexLock &mutex)
:mutex_(mutex)
{
TINY_CHECK(!pthread_cond_init(&cond_, NULL));
} Condition::~Condition()
{
TINY_CHECK(!pthread_cond_destroy(&cond_));
} void Condition::wait()
{
assert(mutex_.isLocking()); //wait前必须上锁
TINY_CHECK(!pthread_cond_wait(&cond_, mutex_.getMutexPtr()));
mutex_.restoreMutexStatus(); //还原状态
} void Condition::notify()
{
TINY_CHECK(!pthread_cond_signal(&cond_));
} void Condition::notifyAll()
{
TINY_CHECK(!pthread_cond_broadcast(&cond_));
}

注意wait后面调用了restoreMutexStatus将mutex的状态置为true。

Linux组件封装(二)中条件变量Condition的封装的更多相关文章

  1. python线程条件变量Condition(31)

    对于线程与线程之间的交互我们在前面的文章已经介绍了 python 互斥锁Lock / python事件Event , 今天继续介绍一种线程交互方式 – 线程条件变量Condition. 一.线程条件变 ...

  2. 转载~kxcfzyk:Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解

    Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解   多线程c语言linuxsemaphore条件变量 (本文的读者定位是了解Pthread常用多线程API和Pthread互斥锁 ...

  3. 多线程编程中条件变量和的spurious wakeup 虚假唤醒

    1. 概述 条件变量(condition variable)是利用共享的变量进行线程之间同步的一种机制.典型的场景包括生产者-消费者模型,线程池实现等. 对条件变量的使用包括两个动作: 1) 线程等待 ...

  4. 【react】利用prop-types第三方库对组件的props中的变量进行类型检测

    1.引言--JavaScript就是一个熊孩子   1.1对于JSer们来说,js是自由的,但同时又有许多让人烦恼的地方.javascript很多时候就是这么一个熊孩子,他很多时候并不会像C和java ...

  5. prop-types:该第三方库对组件的props中的变量进行类型检测

    利用prop-types第三方库对组件的props中的变量进行类型检测

  6. 四十二、Linux 线程——线程同步之条件变量之线程状态转换

    42.1 线程状态转换 42.1.1 状态转换图 42.1.2 一个线程计算,多个线程获取的案例 #include <stdio.h> #include <stdlib.h> ...

  7. Linux环境编程之同步(二):条件变量

    相互排斥锁用于上锁,条件变量则用于等待.条件变量是类型为pthread_cond_t的变量.一般使用例如以下函数: #include <pthread.h> int pthread_con ...

  8. 深入解析条件变量(condition variables)

    深入解析条件变量 什么是条件变量(condition variables) 引用APUE中的一句话: Condition variables are another synchronization m ...

  9. Linux多线程实践(8) --Posix条件变量解决生产者消费者问题

    Posix条件变量 int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr); int pthread_co ...

随机推荐

  1. noip 瑞士轮 ————归并排序解法

    背景 在双人对决的竞技性比赛,如乒乓球.羽毛球.国际象棋中,最常见的赛制是淘汰赛和循环赛.前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高.后者的特点是较为公平,偶然性较低,但比赛过程往往十分冗长 ...

  2. 封装一下webform的公用方法:对于软件我把这些全封装在pagebase里面,这样所有的页面只调用一句 Init()即可,其他的全在页面上配置

      /// <summary>         /// 绑定新闻列表,带分页与查询         /// </summary>         /// <param n ...

  3. rootkit 内核函数hook

    转自:https://0x90syntax.wordpress.com/2016/02/21/suterusu-rootkitx86%e4%b8%8earm%e7%9a%84%e5%86%85%e8% ...

  4. Error:Execution failed for task ':app:transformClassesWithDexForDebug'. > com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.Exec

    Error:Execution failed for task ':app:transformClassesWithDexForDebug'.> com.android.build.api.tr ...

  5. Git-stash操作

    git stash git pull git stash pop git stash pop: 从Git栈中读取最近一次保存的内容,恢复工作区的相关内容.由于可能存在多个Stash的内容,所以用栈来管 ...

  6. linux dev设备

    /dev目录的文件都是设备,我们可以像操作文件一样操作设备.但是究竟什么才是设备文件哪?作为程序员不能用代码敲出来的概念我们都是不喜欢的,所以本文用shell来操作体验什么才是/dev文件. 我们执行 ...

  7. POJ 3624.Charm Bracelet-动态规划0-1背包

    Charm Bracelet Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 47876   Accepted: 20346 ...

  8. UVA 10765 Doves and bombs 割点

    最近好懒,堆了好多题没写题解.. 原题链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8& ...

  9. [CP1804]组合数问题2

    题目大意: 给定两个数$n(n\le10^6)$和$k(k\le10^5)$,找到$k$个不同的满足$0\le b\le a\le n$的组合数$\binom a b$,求这$k$个组合数的最大值. ...

  10. lua的table.sort

    local aa = {{a=11},{a=44},{a=33},{a=2} } table.sort(aa,function(a,b) return a.a>b.a end) for k, v ...