初始化条件变量

int pthread_cond_init(pthread_cond_t *cond,const pthread_condattr_t *attr);

返回值:函数成功返回0;任何其他返回值都表示错误

初始化一个条件变量。当参数attr为空指针时,函数创建的是一个缺省的条件变量。

阻塞

int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);

wait需要传入已经lock的mutex变量。进入wait函数会自动解锁mutex参数指向的互斥锁,并使当前线程阻塞在cond参数指向的条件变量上。当线程被唤醒,退出wait函数时会自动对锁再次进行加锁,成功后返回。

被阻塞的线程可以被pthread_cond_signal函数,pthread_cond_broadcast函数唤醒。一般一个条件表达式都是在一个互斥锁的保护下被检查。当条件表达式未被满足时,线程将仍然阻塞在这个条件变量上。当另一个线程改变了条件的值并向条件变量发出信号时,等待在这个条件变量上的一个线程或所有线程被唤醒,接着都试图再次占有相应的互斥锁。

int pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex, const structtimespec * abstime);

函数到了一定的时间,即使条件未发生也会解除阻塞。这个时间由参数abstime指定。

唤醒

int pthread_cond_signal(pthread_cond_t *cond);

函数被用来释放被阻塞在指定条件变量上的一个线程。唤醒阻塞在条件变量上的所有线程的顺序由调度策略决定,如果线程的调度策略是SCHED_OTHER类型的,系统将根据线程的优先级唤醒线程。

int pthread_cond_broadcast(pthread_cond_t *cond);

函数唤醒所有被pthread_cond_wait函数阻塞在某个条件变量上的线程,参数cond被用来指定这个条件变量。

释放条件变量

int pthread_cond_destroy(pthread_cond_t *cond);

一个例子:

#include <stdio.h>#include <pthread.h>#include <unistd.h>pthread_mutex_t count_lock;pthread_cond_t count_nonzero;unsigned count = 0;void *decrement_count(void *arg){pthread_mutex_lock(&count_lock);printf("decrement_count get count_lock/n");while(count == 0){printf("decrement_count count == 0 /n");printf("decrement_count before cond_wait /n");pthread_cond_wait(&count_nonzero, &count_lock);printf("decrement_count after cond_wait /n");}count = count - 1;pthread_mutex_unlock(&count_lock);}void *increment_count(void *arg){pthread_mutex_lock(&count_lock);printf("increment_count get count_lock /n");if(count == 0){printf("increment_count before cond_signal /n");pthread_cond_signal(&count_nonzero);printf("increment_count after cond_signal /n");}count = count + 1;pthread_mutex_unlock(&count_lock);}int main(void){pthread_t tid1, tid2;pthread_mutex_init(&count_lock, NULL);pthread_cond_init(&count_nonzero, NULL);pthread_create(&tid1, NULL, decrement_count, NULL);sleep(2);pthread_create(&tid2, NULL, increment_count, NULL);sleep(10);pthread_exit(0);return 0;}

运行结果:

decrement_count get count_lock
decrement_count count == 0 
decrement_count before cond_wait 
increment_count get count_lock 
increment_count before cond_signal 
increment_count after cond_signal 
decrement_count after cond_wait

调试程序的运行过程:

1、开始时 counter 为0 (main)

2、首先生成一个thrd1线程运行decrement_counter(),此线程内函数运行流程为:

先锁定 互斥锁(count_lock) 如果counter为0,此线程被阻塞在条件变量(count_nonzero)上.同时释放互斥锁count_lock(wait函数内部会先释放锁,等待signal激活后自动再加上锁).

3、与此同时主程序还在运行,创建另一个线程thrd2运行 increment_counter,此线程内的函数流程如下:

先锁定 互斥锁(count_lock)(wait内部释放锁的互斥锁) 如果counter为0, 唤醒在条件变量(count_nonzero)上的线程即thrd1.但是由于互斥锁count_lock被当前thrd2锁住(signal激活后,线程1的wait内部需要对count_lock上锁), thrd1还是在等待. 然后thrd2中对count+1,释放互斥锁。此时thrd1由于互斥锁释放得以运行,重新判断counter是不是为0,如果为0再把线程阻塞在条件变量count_nonzero上,但这时counter已经为1了.所以线程继续运行.counter-1释放互斥锁(退出后,运行主线程main

生产者消费者例子:

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>#define ERR_EXIT(m)\do \{ \perror(m); \exit(EXIT_FAILURE); \}while(0)#define CONSUMERS_COUNT 2
#define PRODUCERS_COUNT 1pthread_mutex_t g_mutex;
pthread_cond_t g_cont;int iread;pthread_t g_thread[CONSUMERS_COUNT+PRODUCERS_COUNT];void* produce(void* arg)
{while(1){pthread_mutex_lock(&g_mutex);iread++;   //生产printf("product iread=%d\n",iread);pthread_cond_signal(&g_cont);printf("produce is produat\n");pthread_mutex_unlock(&g_mutex);sleep(3);}return NULL;
}
void* consumer(void* arg)
{while(1){pthread_mutex_lock(&g_mutex);printf("consumer iread =%d\n",iread); while(iread==0)  //需要等待生产者生产{pthread_cond_wait(&g_cont, &g_mutex);printf("iread is changed\n");}iread--;  //消费sleep(1);pthread_mutex_unlock(&g_mutex);}return NULL;
} int main()
{int i;pthread_mutex_init(&g_mutex,NULL);pthread_cond_init(&g_cont,NULL);for(i=0; i< PRODUCERS_COUNT;i++){pthread_create(&g_thread[i],NULL,produce,(void*)i);}for(i=0; i< CONSUMERS_COUNT;i++){pthread_create(&g_thread[i+ PRODUCERS_COUNT],NULL,consumer,(void*)i);}for(i=0; i< PRODUCERS_COUNT+CONSUMERS_COUNT;i++){pthread_join(g_thread[i],NULL);}pthread_mutex_destroy(&g_mutex);pthread_cond_destroy(&g_cont);return 0;
}

POSIX条件变量API函数相关推荐

  1. Linux多线程实践(8) --Posix条件变量解决生产者消费者问题

    Posix条件变量 int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr); int pthread_co ...

  2. Linux多线程实践(六)使用Posix条件变量解决生产者消费者问题

    前面的一片文章我们已经讲过使用信号量解决生产者消费者问题.那么什么情况下我们须要引入条件变量呢? 这里借用  http://www.cnblogs.com/ngnetboy/p/3521547.htm ...

  3. linux网络编程之posix 线程(四):posix 条件变量与互斥锁 示例生产者--消费者问题

    http://blog.csdn.net/jnu_simba/article/details/9129939 一.posix 条件变量 一种线程间同步的情形:线程A需要等某个条件成立才能继续往下执行, ...

  4. C11头文件threads.h声明了创建和管理线程,信号,条件变量的函数

    作者Danny Kalev 是通过以色列系统分析师协会认证的系统分析师, 并且是专攻C++的软件工程师. Kalev 写了多本C++的书籍,同时给不同的软件开发者站点投搞C++文章. 他是C++标准委 ...

  5. Linux系统编程---17(条件变量及其函数,生产者消费者条件变量模型,生产者与消费者模型(线程安全队列),条件变量优点,信号量及其主要函数,信号量与条件变量的区别,)

    条件变量 条件变量本身不是锁!但它也可以造成线程阻塞.通常与互斥锁配合使用.给多线程提供一个会合的场所. 主要应用函数: pthread_cond_init 函数 pthread_cond_destr ...

  6. POSIX 条件变量

    1.条件变量 (1)当一个线程互斥地访问某个变量时,它可能发现在其它线程改变状态之前,它什么也做不了.例如:一个线程访问队列时,发现队列为空,它只能等待,直到其它线程将节点添加到队列中.这种情况就需要 ...

  7. POSIX互斥锁api函数

    初始化互斥锁 int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t *attr); 参数attr指定了新建互斥 ...

  8. 标准C函数库头文件、POSIX标准库头文件和Windows API函数库头文件说明

    1. 标准C函数库头文件 名字 源自 描述 <assert.h> 包含断言宏,被用来在程序的调试版本中帮助检测逻辑错误以及其他类型的bug. <complex.h> C99 一 ...

  9. POSIX多线程编程-条件变量pthread_cond_t

    条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足,它常和互斥锁一起使用.使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化.一旦其它 ...

最新文章

  1. 2021年春季学期-信号与系统-第九次作业参考答案-第二小题
  2. c# asp.net Pdf 转换图片 在线预览 发布到iis中问题 最终解决篇—_—!
  3. 任务栏网速监控工具NetSpeedMonitor
  4. xp服务器文档在哪里,如何在XP系统中创建文件服务器
  5. JUC多线程:系统调用、进程、线程的上下文切换
  6. python多线程编程(3): 使用互斥锁同步线程
  7. 加速你的IDE !!!送9个固态硬盘(金士顿240G SSD)
  8. python爬取了百万知乎,并做数据分析
  9. MySQL中查询字段为空或者为null方法
  10. VC 获取Windows所有用户的用户名
  11. kotlin中文开发文档+视频教程+Android Studio 3.0下载地址
  12. 基于双生视界的live2d提取与查看方法
  13. 十大网站压力测试软件-- WEB压力测试工具介绍
  14. postman下载文件乱码
  15. python 压缩 解压文件
  16. Ubuntu 关闭 onboard (屏幕键盘应用)开机自启
  17. 权限管理需要哪几张表
  18. 7年老Android一次操蛋的面试经历,讲的明明白白!
  19. 电池电量与电压的关系
  20. 【SSL】2344 【洛谷】2835刻录光盘

热门文章

  1. Flink的Table API 与SQL的流处理
  2. linux java 共享内存_Linux进程间通信之共享内存
  3. oracle磁带库清洁带标签,磁带库、磁带机和介质支持
  4. python绘制数字23_Python 画数码数字8
  5. 如果再这么玩下去,中国的科研就没戏了
  6. 降低软件复杂性一般原则和方法
  7. 史上最全Java多线程面试60题,含答案大赠送!
  8. 论文浅尝 | Wordly Wise(WoW) - 用于语音视觉知识问答的跨语言知识融合模型
  9. phpmyadmin登陆错误:The requested URL /phpmyadmin was not found on this serve
  10. jquery 快速入门二