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

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. 从零开始学JavaScript三(变量)

    一.变量 ECMAscript变量是松散型变量,所谓松散型变量,就是变量名称可以保存任何类型的数据,每个变量仅仅是一个用于保存值的占位符. 定义变量时要使用var操作符 如: var message; ...

  2. 算法笔记_181:历届试题 回文数字(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 观察数字:12321,123321 都有一个共同的特征,无论从左到右读还是从右向左读,都是相同的.这样的数字叫做:回文数字. 本题要求你找 ...

  3. MySQL 分库备份

    mysql -uroot -p'password' -e "show databases;"|grep -Evi "database|infor|perfor" ...

  4. 解决 $ npm install node-sass --save-dev 失败的问题

    $ npm install --save node-sass --registry=https://registry.npm.taobao.org --disturl=https://npm.taob ...

  5. eclipse中java项目转成Web项目

    1.找到项目目录下的.project文件 2.编辑.project文件,找到<natures>...</natures> 3.2中找到的结点中加下面的的代码 <natur ...

  6. use of _track and track_visibility

    Dosen't work...the followers don't recieve an email when the state is change. Here is the code in th ...

  7. 【基于Android的ARM汇编语言系列】之三:ARM汇编语言程序结构

    作者:郭嘉 邮箱:allenwells@163.com 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWell [ ...

  8. eclipse to avoid the message, disable the...

      标题 CreateTime--2018年5月9日10:38:15 Author:Marydon 1.问题描述 2.问题解析 这是因为eclipse的智能提示超时引起的,将超时间调大即可,如:200 ...

  9. 〖Ruby〗Ruby运算符/优先级

    优先级 能否重写 运行符 描述 最高 Y [] []= 数组下标 数组元素赋值 Y ** 冥乘 Y ! ~ + - 非 位非 一元加 负号 Y * / % 乘 除 模 Y + - 加 减 Y > ...

  10. Windows下如何配置tomcat环境变量

    Apache Tomcat 是一款 Java Servlet 和 JavaServer Pages 技术的开源软件实现,可以作为测试 Servlet 的独立服务器,而且可以集成到 Apache Web ...