c++ 条件变量

http://blog.csdn.net/hemmanhui/article/details/4417433

互斥锁:用来上锁。

条件变量:用来等待,当条件变量用来自动阻塞一个线程,直到某特殊情况发生为止。通常条件变量和互斥锁同时使用。

函数介绍:

名称:

pthread_cond_init

目标:

条件变量初始化

头文件:

include < pthread.h>

函数原形:

int pthread_cond_init(pthread_cond_t cond, const pthread_condattr_t attr);

参数:

cptr 条件变量

attr 条件变量属性

返回值:

成功返回0,出错返回错误编号。

pthread_cond_init函数可以用来初始化一个条件变量。他使用变量attr所指定的属性来初始化一个条件变量,如果参数attr为空,那么它将使用缺省的属性来设置所指定的条件变量。

名称:

pthread_cond_destroy

目标:

条件变量摧毁

头文件:

include < pthread.h>

函数原形:

int pthread_cond_destroy(pthread_cond_t *cond);

参数:

cptr 条件变量

返回值:

成功返回0,出错返回错误编号。

名称:

pthread_cond_wait/pthread_cond_timedwait

目标:

条件变量等待

头文件:

include < pthread.h>

函数原形:

int pthread_cond_wait(pthread_cond_t cond,pthread_mutex_t mutex);

int pthread_cond_timedwait(pthread_cond_t cond,pthread_mutex_t mytex,const struct timespec abstime);

参数:

cond 条件变量

mutex 互斥锁

返回值:

成功返回0,出错返回错误编号。

第一个参数cond是指向一个条件变量的指针。第二个参数mutex则是对相关的互斥锁的指针。函数pthread_cond_timedwait函数类型与函数pthread_cond_wait,区别在于,如果达到或是超过所引用的参数abstime,它将结束并返回错误ETIME.pthread_cond_timedwait函数的参数abstime指向一个timespec结构。该结构如下:

typedef struct timespec{

time_t tv_sec;

long tv_nsex;

}timespec_t;

名称:

pthread_cond_signal/pthread_cond_broadcast

目标:

条件变量通知

头文件:

include < pthread.h>

函数原形:

int pthread_cond_signal(pthread_cond_t *cond);

int pthread_cond_broadcast(pthread_cond_t *cond);

参数:

cond 条件变量

返回值:

成功返回0,出错返回错误编号。

参数cond是对类型为pthread_cond_t 的一个条件变量的指针。当调用pthread_cond_signal时一个在相同条件变量上阻塞的线程将被解锁。如果同时有多个线程阻塞,则由调度策略确定接收通知的线程。如果调用pthread_cond_broadcast,则将通知阻塞在这个条件变量上的所有线程。一旦被唤醒,线程仍然会要求互斥锁。如果当前没有线程等待通知,则上面两种调用实际上成为一个空操作。如果参数cond指向非法地址,则返回值EINVAL。

下面是一个简单的例子,我们可以从程序的运行来了解条件变量的作用。

include

sleep(1);
}

}

void thread2(void junk)
{
while(i

if(i%3!=0)
pthread_cond_wait(&cond,&mutex);/等待/
printf(“thread2:%d/n”,i);
pthread_mutex_unlock(&mutex);

sleep(1);
}

程序创建了2个新线程使他们同步运行,实现进程t_b打印20以内3的倍数,t_a打印其他的数,程序开始线程t_b不满足条件等待,线程t_a运行使a循环加1并打印。直到i为3的倍数时,线程t_a发送信号通知进程t_b,这时t_b满足条件,打印i值。

下面是运行结果:

cc –lpthread –o cond cond.c

./cond

thread1:1

thread1:2

thread2:3

thread1:4

thread1:5

thread2:6

thread1:7

thread1:8

thread2:9

备注:

pthread_cond_wait 执行的流程首先将这个mutex解锁, 然后等待条件变量被唤醒, 如果没有被唤醒, 该线程将一直休眠, 也就是说, 该线程将一直阻塞在这个pthread_cond_wait调用中, 而当此线程被唤醒时, 将自动将这个mutex加锁,然后再进行条件变量判断(原因是”惊群效应”,如果是多个线程都在等待这个条件,而同时只能有一个线程进行处理,此时就必须要再次条件判断,以使只有一个线程进入临界区处理。),如果满足,则线程继续执行,最后解锁,

也就是说pthread_cond_wait实际上可以看作是以下几个动作的合体:
解锁线程锁
等待线程唤醒,并且条件为true
加锁线程锁.

pthread_cond_signal仅仅负责唤醒正在阻塞在同一条件变量上的一个线程,如果存在多个线程,系统自动根据调度策略决定唤醒其中的一个线程,在多处理器上,该函数是可能同时唤醒多个线程,同时该函数与锁操作无关,解锁是由pthread_mutex_unlock(&mutex)完成

唤醒丢失往往会在下面的情况下发生:

一个线程调用pthread_cond_signal或pthread_cond_broadcast函数; 另一个线程正处在测试条件变量和调用pthread_cond_wait函数之间; 没有线程正在处在阻塞等待的状态下

Original: https://www.cnblogs.com/i80386/p/5028875.html
Author: 雨渐渐
Title: c++ 条件变量

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/535330/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 用C/C++实现对STORM的执行信息查看和控制

    近期公司有个需求。须要在后端应用server上实时获取STORM集群的执行信息和topology相关的提交和控制,经过几天对STORM UI和CMD源代码的分析,得出能够通过其th…

    C++ 2023年5月29日
    092
  • [C++] 对象指针使用方法

    对象指针:指向类对象的指针 类指针指向类变量(对象)的地址 对象指针定义格式: 举例: #include using namespace std; class Student { …

    C++ 2023年5月29日
    070
  • C++ lambda 用法

    为什么要使用lambda 就地匿名的定义一个目标函数或者函数对象,不需要额外的再写一个命名函数或者函数对象,以更直接的方式去写函数,可以调高程序的可读性和可维护性。 简洁:不要额外…

    C++ 2023年5月29日
    082
  • c++ 类的堆成员的声明及使用

    _reg = new boost::regex("aoe "); boost::regex_search(line, what, *_reg) Original…

    C++ 2023年5月29日
    073
  • C++17新特性

    C++17新特性 前言 If Statements with Initializer Constexpr if inline 变量 嵌套命名空间 属性说明符 [[fallthrou…

    C++ 2023年5月29日
    070
  • C++ STL std::copy 详解

    std::copy(start, end, std::back_inserter(container)); 这里,start和end是输入序列(假设有N个元素)的迭代器(itera…

    C++ 2023年5月29日
    086
  • C#与c++对应的类型

    C#与c++对应的类型 csharp;gutter:true; C#调用C++的DLL搜集整理的所有数据类型转换方式-转载</p> <pre><cod…

    C++ 2023年5月29日
    051
  • c/c++本地时间获取

    在记录程序日志时,需要记录时间。如下: 即Y为年、m为月、d为日、X为具体时分秒、A为星期、j为天数、z为其他,结果如下: 如果通过函数返回,需要这样: 其中,char tmp[6…

    C++ 2023年5月29日
    072
  • C++强大背后

    在31年前(1979年),一名刚获得博士学位的研究员,为了开发一个软件项目发明了一门新编程语言,该研究员名为Bjarne Stroustrup,该门语言则命名为——C with c…

    C++ 2023年5月29日
    073
  • C++:vector中的resize()函数 VS reserve()函数

    http://www.cplusplus.com/reference/vector/vector/vector/ 写代码的时候无意错用了这两个函数 导致测试的时候,程序运行崩溃 发…

    C++ 2023年5月29日
    076
  • C++菜鸟经验:如何有效地避免各种不期而遇的Bug

    本文展示了笔者在编写 C++程序中遇到的问题和解决方案。文中附有大量有用的代码,这些代码往往都可以不加修改的添加进你自己的函数包中。你可能不能在其他的书上找到这些写法,因为这些都是…

    C++ 2023年5月29日
    056
  • Model/View结构(整理自<Qt5.9 C++开发指南>)

    数据模型 数据不仅可以存储在数据模型中,数据可以是其他类,文件,数据库或任何数据源. 视图组件 那些带View的类; 在显示数据时,调用setModel()函数,为自己设置一个数据…

    C++ 2023年5月29日
    077
  • [C++] namespace命名空间和using用法

    命名空间namespace:指标识符的各种可见范围。 C++标准程序库中的所有标识符都被定义在一个std的namespace,这就是程序开始添加 using namespace s…

    C++ 2023年5月29日
    074
  • C++常用的设计模式

    单例模式: 单例模式:确保一个类只有一个实例,并且这个实例化向整个系统提供 (例如只有一台打印机,可以有多个打印任务队列,但是只能有一个正在打印)。单例模式又分为(饿汉模式,懒汉模…

    C++ 2023年5月29日
    065
  • 关于C++ const 的全面总结

    C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助。 Const 是C++中常用的类型修饰…

    C++ 2023年5月29日
    064
  • [C++] 浅拷贝和深拷贝

    浅拷贝只是简单的值拷贝; 深拷贝需要重新分配空间。 系统默认的拷贝构造函数属于浅拷贝。 输出结果为: HelloHelloWorldWorld 为什么修改对象 m 的值,对象 n …

    C++ 2023年5月29日
    076
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球