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条件变量的更多相关文章

  1. pthread 条件变量

    在上一篇博客互斥量中,解决了线程如何互斥访问临界资源的问题. 在开始本文之前,我们先保留一个问题:为什么需要条件变量,如果只有互斥量不能解决什么问题? API init/destroy 条件变量的数据 ...

  2. 转载~kxcfzyk:Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解

    Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解   多线程c语言linuxsemaphore条件变量 (本文的读者定位是了解Pthread常用多线程API和Pthread互斥锁 ...

  3. pthread中互斥量,锁和条件变量

    互斥量 #include <pthread.h> pthread_mutex_t mutex=PTHREAD_MUTEX_INTIIALIZER; int pthread_mutex_in ...

  4. 互斥锁和条件变量(pthread)相关函数

    互斥锁 #include <pthread.h> // 若成功返回0,出错返回正的Exxx值 // mptr通常被初始化为PTHREAD_MUTEX_INITIALIZER int pth ...

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

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

  6. linux线程同步(2)-条件变量

    一.概述                                                    上一篇,介绍了互斥量.条件变量与互斥量不同,互斥量是防止多线程同时访问共享的互斥变量来保 ...

  7. 条件变量pthread_cond_t怎么用

    #include <pthread.h> #include <stdio.h> #include <stdlib.h> pthread_mutex_t mutex ...

  8. [转]一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程

    一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程 希望此文能给初学多线程编程的朋友带来帮助,也希望牛人多多指出错误. 另外感谢以下链接的作者给予,给我的学习带来了很大帮助 http ...

  9. linux多线程-互斥&条件变量与同步

    多线程代码问题描述 我们都知道,进程是操作系统对运行程序资源分配的基本单位,而线程是程序逻辑,调用的基本单位.在多线程的程序中,多个线程共享临界区资源,那么就会有问题: 比如 #include < ...

随机推荐

  1. [LOJ#6437][BZOJ5373]「PKUSC2018」PKUSC

    [LOJ#6437][BZOJ5373]「PKUSC2018」PKUSC 试题描述 九条可怜是一个爱玩游戏的女孩子. 最近她在玩一个无双割草类的游戏,平面上有 \(n\) 个敌人,每一个敌人的坐标为 ...

  2. cdh版本的hadoop安装及配置(伪分布式模式) MapReduce配置 yarn配置

    安装hadoop需要jdk依赖,我这里是用jdk8 jdk版本:jdk1.8.0_151 hadoop版本:hadoop-2.5.0-cdh5.3.6 hadoop下载地址:链接:https://pa ...

  3. 【BZOJ 3172】[Tjoi2013]单词 AC自动机

    关于AC自动机:一个在kmp与Trie的基础上建立的数据结构,关键在于Trie树结构与fail指针,他们各有各的应用.在AC自动机里最典型的就是多串匹配,原本效率为O(n*l+n*l+m*l),(n是 ...

  4. Socket和ServerSocket学习笔记

    对于即时类应用或者即时类的游戏,HTTP协议很多时候无法满足于我们的需求.这会,Socket对于我们来说就非常实用了.下面是本次学习的笔记.主要分异常类型.交互原理.Socket.ServerSock ...

  5. windows 系统下git 的使用

    前言: 最新版本的git for windows也是有界面的,不再是以前的纯命令行操作,但是我习惯了乌龟,所以感觉还是直接用乌龟比较方便点~~ 前提,已安装以下: git for windows,未安 ...

  6. Junit使用的超简单介绍

    Junit使用的超简单介绍 前言:我对Junit了解的并不多,只是今天突然听到有人提到了它,而且现在时间还早,所以我觉得我不妨更一篇关于Junit4的超级超级简单的用法,全当是为了省去看官网demo的 ...

  7. 【Foreign】阅读 [线段树][DP]

    阅读 Time Limit: 10 Sec  Memory Limit: 256 MB Description Input Output Sample Input 0 10 4 10 2 3 10 8 ...

  8. 关于dlib人脸对比,人脸识别

    人脸检测 人脸特征点提取 人脸对比,等于两张人脸对比,识别 封装的所有识别函数,直接看下面调用就好了. # coding:utf-8 ''' 本本次封装,我主要是做两张人脸对比. 就只人脸识别部分,简 ...

  9. Linux服务器中毒事件(libudev.so)

    今天机房管理人员反馈公司的某台服务器在防火墙上的连接数超限,登陆服务器时发现非常卡顿,远程登录后查看,CPU持续100%,且有一长度为10的随机字符串进程,kill掉,会重新生成另外长度为10的字符串 ...

  10. Django【进阶】信号

    -信号 Django中提供了“信号调度”,用于在框架执行操作时解耦.通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒一些接受者.   问题:如何对所有数据库添加操作进行日志记录? 问题:信 ...