pthread条件变量
pthread条件变量等待条件有两种方式:无条件等待pthread_cond_wait()和计时等待pthread_cond_timedwait(),其中计时等待方式如果在给定时刻前条件没有满足,则返回ETIMEOUT,结束等待,其中abstime以与time()系统调用相同意义的绝对时间形式出现,0表示格林尼治时间1970年1月1日0时0分0秒。
无论哪种等待方式,都必须和一个互斥锁配合,以防止多个线程同时请求pthread_cond_wait()(或pthread_cond_timedwait())的竞争条件。mutex互斥锁必须是普通锁(PTHREAD_MUTEX_TIMED_NP)或者适应锁(PTHREAD_MUTEX_ADAPTIVE_NP),且在调用pthread_cond_wait()前必须由本线程加锁(pthread_mutex_lock()),而在更新条件等待队列以前,mutex保持锁定状态,并在线程挂起进入等待前解锁。在条件满足从而离开pthread_cond_wait()之前,mutex将被重新加锁,以与进入pthread_cond_wait()前的加锁动作对应。
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h> static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; struct node {
int n_number;
struct node *n_next;
} *head = NULL; // 线程清理函数
static void cleanup_handler(void *arg)
{
printf("Cleanup handler of second thread.\n");
free(arg);
(void)pthread_mutex_unlock(&mtx);
} static void *thread_func(void *arg)
{
struct node *p = NULL; pthread_cleanup_push(cleanup_handler, p);
while (true) {
//这个mutex主要是用来保证pthread_cond_wait的并发性
pthread_mutex_lock(&mtx); /*
因为pthread_cond_wait里的线程可能会被意外唤醒,
如果这个时候head != NULL,则不是我们想要的情况。
这个时候,应该让线程继续进入pthread_cond_wait
*/
while (head == NULL) {
/*
pthread_cond_wait会先解除之前的pthread_mutex_lock锁定的mtx,
然后阻塞在等待对列里休眠,直到再次被唤醒(大多数情况下是等待的条件成立而被唤醒,
唤醒后,该进程会先锁定先pthread_mutex_lock(&mtx);再读取资源
用这个流程是比较清楚的block-->unlock-->wait() return-->lock
*/
pthread_cond_wait(&cond, &mtx);
}
p = head;
head = head->n_next;
printf("Got %d from front of queue\n", p->n_number);
free(p);
//临界区数据操作完毕,释放互斥锁
pthread_mutex_unlock(&mtx);
}
pthread_cleanup_pop();
return ;
} int main(void)
{
pthread_t tid;
int i;
struct node *p;
pthread_create(&tid, NULL, thread_func, NULL); for (i = ; i < ; i++) {
p = (struct node*)malloc(sizeof(struct node));
p->n_number = i; // 加锁->signal->解锁
pthread_mutex_lock(&mtx);
p->n_next = head;
head = p;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mtx);
sleep();
}
printf("cancel thread\n");
/*
从外部终止子线程,子线程会在最近的取消点,退出线程
最近的取消点肯定就是pthread_cond_wait()了。
*/
pthread_cancel(tid);
// 等待cancel完成,不然可能不会执行到cleanup。
pthread_join(tid, NULL);
printf("All done -- exiting\n");
return ;
}
pthread_cleanup_push来注册清理函数rtn,这个函数有一个参数arg。在以下三种情形之一发生时,注册的清理函数被执行:
1)调用pthread_exit。
2)作为对取消线程请求(pthread_cancel)的响应。
3)以非0参数调用pthread_cleanup_pop。
注意:
1)如果线程只是由于简单的返回而终止的,则清除函数不会被调用。
2)如果pthread_cleanup_pop被传递0参数,则清除函数不会被调用,但是会清除处于栈顶的清理函数。
pthread条件变量的更多相关文章
- pthread 条件变量
在上一篇博客互斥量中,解决了线程如何互斥访问临界资源的问题. 在开始本文之前,我们先保留一个问题:为什么需要条件变量,如果只有互斥量不能解决什么问题? API init/destroy 条件变量的数据 ...
- 转载~kxcfzyk:Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解
Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解 多线程c语言linuxsemaphore条件变量 (本文的读者定位是了解Pthread常用多线程API和Pthread互斥锁 ...
- pthread中互斥量,锁和条件变量
互斥量 #include <pthread.h> pthread_mutex_t mutex=PTHREAD_MUTEX_INTIIALIZER; int pthread_mutex_in ...
- 互斥锁和条件变量(pthread)相关函数
互斥锁 #include <pthread.h> // 若成功返回0,出错返回正的Exxx值 // mptr通常被初始化为PTHREAD_MUTEX_INITIALIZER int pth ...
- Linux 多线程条件变量同步
条件变量是线程同步的另一种方式,实际上,条件变量是信号量的底层实现,这也就意味着,使用条件变量可以拥有更大的自由度,同时也就需要更加小心的进行同步操作.条件变量使用的条件本身是需要使用互斥量进行保护的 ...
- linux线程同步(2)-条件变量
一.概述 上一篇,介绍了互斥量.条件变量与互斥量不同,互斥量是防止多线程同时访问共享的互斥变量来保 ...
- 条件变量pthread_cond_t怎么用
#include <pthread.h> #include <stdio.h> #include <stdlib.h> pthread_mutex_t mutex ...
- [转]一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程
一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程 希望此文能给初学多线程编程的朋友带来帮助,也希望牛人多多指出错误. 另外感谢以下链接的作者给予,给我的学习带来了很大帮助 http ...
- linux多线程-互斥&条件变量与同步
多线程代码问题描述 我们都知道,进程是操作系统对运行程序资源分配的基本单位,而线程是程序逻辑,调用的基本单位.在多线程的程序中,多个线程共享临界区资源,那么就会有问题: 比如 #include < ...
随机推荐
- 【BZOJ 2434】 [Noi2011]阿狸的打字机 fail树+树状数组
就是考了一个fail树的神奇应用我们建出fail树之后,发现我们就是在求y到根的路径上所有的点在以x为根的子树里的个数,这个我们离线后用树状数组+dfs序即可解决 #include <cstdi ...
- dhcp 和ntpdate时间同步
为了防止路由器的dhcp服务干扰实验,我们2台机器分别新加了1快网卡. vmnet4 dhcp安装 [root@ygy130 ~]# yum -y install dhcp 将配置文件放在/etc/d ...
- JS让任意图片垂直水平居中且页面不滚动
说一下以前遇到的一个问题: 假设有一张小图,要实现点击查看大图的功能,而这个图的宽高可能会超过浏览器的宽高,这时候我们通过JS来改变图片的宽高,从而实现图片在浏览器居中显示且不滚屏. 方法如下: 首先 ...
- 做一个所见即所得的CSS效果
style 也是标签(在非ie内核的浏览器中支持),我们将style设置成 contenteditable的时候,那么那的内容就可以编辑了.仔细的体验下,如果我们将背景修改成红色的.那么只要书写完,立 ...
- Codeforces Round #351 (VK Cup 2016 Round 3, Div. 2 Edition) B
B. Problems for Round time limit per test 2 seconds memory limit per test 256 megabytes input standa ...
- POJ3660:Cow Contest(Floyd传递闭包)
Cow Contest Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16941 Accepted: 9447 题目链接 ...
- android studio的弹出层
<activity android:name=".SecondActivity" android:theme="@style/Theme.AppCompat.Dia ...
- rpm的使用:查询、安装、卸载、升级
RPM 有五种操作模式,分别为:安装.卸载.升级.查询和验证. RPM 安装操作 命令: rpm -i 需要安装的包文件名 举例如下: rpm -i example.rpm 安装 example.rp ...
- bzoj 3720 Gty的妹子树 树分块?瞎搞
Gty的妹子树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2149 Solved: 781[Submit][Status][Discuss] D ...
- c++(类继承)示例[仅用于弱弱的博主巩固知识点用哦,不好勿喷]
测试代码: Animals.h: #pragma once #include<string> class Animals { protected: std::string Food; in ...