条件变量是用来通知共享数据状态信息的。

1.条件变量初始化两种方式:
(1)静态初始化
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
代码示例如下:

#include <pthread.h>
typedef struct my_struct_tag {
pthread_mutex_t mutex; /* Protects access to value */
pthread_cond_t cond; /* Signals change to value */
int value; /* Access protected by mutex */
} my_struct_t; my_struct_t data = {
PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, }; int main (int argc, char *argv[])
{
return ;
}

(2)动态初始化
int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *condattr);
int pthread_cond_destroy(pthread_cond_t *cond);
代码示例如下:

#include <pthread.h>

typedef struct my_struct_tag {
pthread_mutex_t mutex; /* Protects access to value */
pthread_cond_t cond; /* Signals change to value */
int value; /* Access protected by mutex */
} my_struct_t; int main (int argc, char *argv[])
{
my_struct_t *data;
int status;
data = malloc (sizeof (my_struct_t));
status = pthread_mutex_init (&data->mutex, NULL);
status = pthread_cond_init (&data->cond, NULL);
status = pthread_cond_destroy (&data->cond);
status = pthread_mutex_destroy (&data->mutex);
(void)free (data);
return status;
}

2.等待条件变量
int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex,struct timespec *expiration);
当线程等待条件变量时,它必须将相关互斥量锁住。在阻塞线程之前,条件变量等待操作将解锁互斥量,而在重新返回线程之前,会再次锁住互斥量。

3.唤醒条件变量
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
在发送信号时也必须锁住互斥量,如果互斥量不被锁住,任何线程可以在被唤醒线程之前锁住互斥量。这将是一个产生被拦截唤醒的根源。例如,一个低优先级的线程可能锁住了互斥量,使高优先级的线程无法被其他线程唤醒,延迟了高优先级线程的调度。

4.需要在等待条件变量线程被唤醒后,检测条件
(1)被拦截的唤醒:等待条件变量被唤醒并加锁相关互斥量,若一个其他线程获得了互斥量,它可能在等待之前先检查条件。由于条件为真,所以它不需等待,直接处理工作,当它解锁时,已经没有可做的工作了。我们的第一个等待条件变量线程加锁互斥量后,再次检测条件,很有必要。
(2)松散的条件:使用不确定的条件时,循环检测条件,代码会更加健壮。
(3)假唤醒:在某些多处理器系统,会发生假唤醒的情况。

5.使用示例

主线程等待条件信号2S,子线程睡眠1S,改变共享数据值,发送信号,主线程接收信号,继续运行。

#include<stdio.h>
#include<pthread.h>
#include<errno.h>
typedef struct cond_tag
{
pthread_mutex_t mutex;
pthread_cond_t cond;
int valid;
}cond_t;
cond_t data = {
PTHREAD_MUTEX_INITIALIZER,
PTHREAD_COND_INITIALIZER, };
void *thread_route(void *arg)
{
sleep();
pthread_mutex_lock(&data.mutex);
data.valid = ;
pthread_cond_signal(&data.cond);
pthread_mutex_unlock(&data.mutex);
return NULL;
}
int main(void)
{
int status;
pthread_t pid;
pthread_create(&pid,NULL,thread_route,NULL);
struct timespec timeout;
timeout.tv_sec = time(NULL)+;
timeout.tv_nsec = ;
pthread_mutex_lock(&data.mutex);
while(data.valid==)
{
status = pthread_cond_timedwait(&data.cond,&data.mutex,&timeout);
if(status==ETIMEDOUT)
{
printf("wait timed out\n");
break;
}
}
if(data.valid==)
{
printf("cond is signaled\n");
}
pthread_mutex_unlock(&data.mutex); return ;
}

参考资料:《POSIX多线程程序设计》 pp.59-74

posix多线程--条件变量的更多相关文章

  1. Linux Qt使用POSIX多线程条件变量、互斥锁(量)

    今天团建,但是文章也要写.酒要喝好,文要写美,方为我辈程序员的全才之路.嘎嘎 之前一直在看POSIX的多线程编程,上个周末结合自己的理解,写了一个基于Qt的用条件变量同步线程的例子.故此来和大家一起分 ...

  2. Linux 多线程条件变量同步

    条件变量是线程同步的另一种方式,实际上,条件变量是信号量的底层实现,这也就意味着,使用条件变量可以拥有更大的自由度,同时也就需要更加小心的进行同步操作.条件变量使用的条件本身是需要使用互斥量进行保护的 ...

  3. C++11并发——多线程条件变量std::condition_variable(四)

    https://www.jianshu.com/p/a31d4fb5594f https://blog.csdn.net/y396397735/article/details/81272752 htt ...

  4. C++多线程の条件变量

    如果有一个队列,方法一和方法二:方法一是生产者,方法二是消费者: 两者不停的相互等待,加减锁,为了减少不必要的等待,我们可以使用条件变量, 条件的变量的第二个参数的加入可以控制多个线程的"消 ...

  5. posix thread条件变量

    概述 等待条件变量总是返回锁住的互斥量. 条件变量的作用是发送信号,而不是互斥. 与条件变量相关的共享数据是“谓词”,如队列满或队列空条件. 一个条件变量应该与一个谓词相关.如果一个条件变量与多个谓词 ...

  6. Linux Posix线程条件变量

    生产者消费者模型 .多个线程操作全局变量n,需要做成临界区(要加锁--线程锁或者信号量) .调用函数pthread_cond_wait(&g_cond,&g_mutex)让这个线程锁在 ...

  7. 笔记3 linux 多线程 条件变量+互斥锁

    //cond lock #include<stdio.h> #include<unistd.h> #include<pthread.h> struct test { ...

  8. Linux多线程编程的条件变量

    在stackoverflow上看到一关于多线程条件变量的问题,题主问道:什么时候会用到条件变量,mutex还不够吗?有个叫slowjelj的人做了很好的回答,我再看这个哥们其他话题的一些回答,感觉水平 ...

  9. (转)Java线程:新特征-条件变量

    Java线程:新特征-条件变量   条件变量是Java5线程中很重要的一个概念,顾名思义,条件变量就是表示条件的一种变量.但是必须说明,这里的条件是没有实际含义的,仅仅是个标记而已,并且条件的含义往往 ...

随机推荐

  1. 谈谈Boost网络编程(2)—— 新系统的设计

    写文章之前.我们一般会想要採用何种方式,是"开门见山",还是"疑问式开头".写代码也有些类似.在编码之前我们须要考虑系统总体方案,这也就是各种设计文档的作用.在 ...

  2. 算法笔记_188:历届试题 危险系数(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 抗日战争时期,冀中平原的地道战曾发挥重要作用. 地道的多个站点间有通道连接,形成了庞大的网络.但也有隐患,当敌人发现了某个站点后,其它站点 ...

  3. Wide - Residual - Inception Networks for R eal - time O bject D etection

    本文的提出了一个WR-inception网络结构.只需更小的内存消耗和更小的计算量. 作者使用了一种微结构,整个宏观网络都是由这个微结构组成. 微结构 微结构的种类如下: 基本的残差结构(3*3,3* ...

  4. vim中的高亮全部同样单词的方法

    用vim时,想高亮显示一个单词并查找的方发.将光标移动到所找单词. 1: shift + "*"  向下查找并高亮显示 2: shift + "#"  向上查找 ...

  5. mysql 运行计划explain具体解释

    explain主要是用来获取一个query的运行计划,描写叙述mysql怎样运行查询操作.运行顺序,使用到的索引,以及mysql成功返回结果集须要运行的行数.能够帮助我们分析 select 语句,让我 ...

  6. exception 值太大

      CreateTime--2018年2月5日09:45:01 Author:Marydon 异常: Cause: java.sql.SQLException: ORA-12899: 列 " ...

  7. Linux磁盘分区及链接文件的特点

    系统分区 传统的分区fdisk 最大支持2T的硬盘分区 对存储,多分区使用的parted 主分区:最多只能有4个 扩展分区 最多只能有1个 主分区加扩展分区最多有4个 不能写入数据,只能包含逻辑分区 ...

  8. 【环境配置】配置ndk

    1. 背景 Android平台从诞生起,就已经支持C.C++开发. 众所周知,Android的SDK基于Java实现.这意味着基于Android SDK进行开发的第三方应用都必须使用Java语言.但这 ...

  9. leetcode621 贪心:任务安排

    题目链接 给定26种任务,每种任务的数量已知. 相同任务之间必须间隔n个时间段,为了不足n个时间段,可以让及其休息. 问:最少需要多长时间才能处理完这些任务? 这道题用贪心策略解决:每次安排任务时,优 ...

  10. 【LeetCode】18. 4Sum (2 solutions)

    4Sum Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d  ...