posix多线程--条件变量
条件变量是用来通知共享数据状态信息的。
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多线程--条件变量的更多相关文章
- Linux Qt使用POSIX多线程条件变量、互斥锁(量)
今天团建,但是文章也要写.酒要喝好,文要写美,方为我辈程序员的全才之路.嘎嘎 之前一直在看POSIX的多线程编程,上个周末结合自己的理解,写了一个基于Qt的用条件变量同步线程的例子.故此来和大家一起分 ...
- Linux 多线程条件变量同步
条件变量是线程同步的另一种方式,实际上,条件变量是信号量的底层实现,这也就意味着,使用条件变量可以拥有更大的自由度,同时也就需要更加小心的进行同步操作.条件变量使用的条件本身是需要使用互斥量进行保护的 ...
- C++11并发——多线程条件变量std::condition_variable(四)
https://www.jianshu.com/p/a31d4fb5594f https://blog.csdn.net/y396397735/article/details/81272752 htt ...
- C++多线程の条件变量
如果有一个队列,方法一和方法二:方法一是生产者,方法二是消费者: 两者不停的相互等待,加减锁,为了减少不必要的等待,我们可以使用条件变量, 条件的变量的第二个参数的加入可以控制多个线程的"消 ...
- posix thread条件变量
概述 等待条件变量总是返回锁住的互斥量. 条件变量的作用是发送信号,而不是互斥. 与条件变量相关的共享数据是“谓词”,如队列满或队列空条件. 一个条件变量应该与一个谓词相关.如果一个条件变量与多个谓词 ...
- Linux Posix线程条件变量
生产者消费者模型 .多个线程操作全局变量n,需要做成临界区(要加锁--线程锁或者信号量) .调用函数pthread_cond_wait(&g_cond,&g_mutex)让这个线程锁在 ...
- 笔记3 linux 多线程 条件变量+互斥锁
//cond lock #include<stdio.h> #include<unistd.h> #include<pthread.h> struct test { ...
- Linux多线程编程的条件变量
在stackoverflow上看到一关于多线程条件变量的问题,题主问道:什么时候会用到条件变量,mutex还不够吗?有个叫slowjelj的人做了很好的回答,我再看这个哥们其他话题的一些回答,感觉水平 ...
- (转)Java线程:新特征-条件变量
Java线程:新特征-条件变量 条件变量是Java5线程中很重要的一个概念,顾名思义,条件变量就是表示条件的一种变量.但是必须说明,这里的条件是没有实际含义的,仅仅是个标记而已,并且条件的含义往往 ...
随机推荐
- java.io.IOException: Input/output error
java.io.FileOutputStream.close0(Native Method)at java.io.FileOutputStream.close(FileOutputStream.jav ...
- PHP採集利器:依据開始字符串和结束字符串截取须要的採集内容数据
PHP採集利器:依据開始字符串和结束字符串截取须要的採集内容数据 function strCutByStr(&$str, $findStart, $findEnd = false, $enco ...
- 使用Fiddler抓包调试https下的页面
众所周知https技术诞生以来,一个很重要的作用就是加密通信内容.所以在项目团队将业务站点实施完https改造以后,原先使用fiddler进行抓包的美好生活到头了.其实fiddler本身是支持对于ht ...
- 设置TreeView背景色
以下为在Csdn上找到的Treeview资源管理器代码,怎样改变其背景色?用:SendMessage SysTreeWindow,TVM_SETBKCOLOR,0,byval RGB(255,255, ...
- 安装itunes时提示不能删除旧版本的apple应用程序支持
下载我 选择需要卸载清理的程序(所有与Apple有关的) ok
- 修复windows Management Instrumentation(WMI)
第一步.重建repository文件夹下所有文件,打开“开始”“运行”输入一下命令并回车:1.停止 WMI 服务, net stop winmgmt2.删除repository文件夹下所有文件, %w ...
- jqGrid删除多行数据问题
var consoleDlg = $("#delcostListDlg"); var selectedRowIds = $("#costList").jqGri ...
- 在Html.ActionLink中运用二维判断语句
@Html.ActionLink("公告信息", "notice", "article", null, new { @class = Vie ...
- eclipse 如何运行mavenWeb项目
1.使用maven 首先,在eclipse中,使用maven对项目进行打包: 其次,将项目发布到Tomcat服务器上 说明: demo_WebService2-0.0.1-SNAPSHOT文件夹存 ...
- C# 获取今天,昨天,上周,下周,上月,下月等等一些日期格式
C#里内置的DateTime基本上都可以实现这些功能,巧用DateTime会使你处理这些事来变轻松多了 今天 DateTime.Now.Date ...