pthread_cond_wait学习笔记
pthread_cond_wait学习笔记
近期学习了线程等待和激活的相关知识。
先介绍几个api:
pthread_cond_t表示多线程的条件变量,用于控制线程等待和就绪的条件。
一:条件变量的初始化:
条件变量和互斥锁一样,都有静态动态两种创建方式,
静态方式使用PTHREAD_COND_INITIALIZER常量初始化。
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
动态方式初始化:
1 首先要new或者malloc一个pthread_cond_t类型变量,
用完后记得delete或者free掉。
2
使用pthread_cond_wait方式如下:
pthread _mutex_lock(&mutex)
while或if(线程执行的条件是否成立)
pthread_cond_wait(&cond, &mutex);
线程执行
pthread_mutex_unlock(&mutex);
对于这点apue给出的解释:The mutex passed to pthread_cond_wait protects the condition.The caller passes it locked to
the function, which then atomically places the calling thread on the list of threads waiting for the condition and unlocks
the mutex. This closes the window between the time that the condition is checked and the time that the
thread goes to sleep waiting for the condition to change, so that the thread doesn't miss a change in the condition.
When pthread_cond_wait returns, the mutex is again locked.
1,线程放在等待队列上,解锁
2,等待 pthread_cond_signal或者pthread_cond_broadcast信号之后去竞争锁
3,若竞争到互斥索则加锁。
使用流程
等待线程:
pthread_mutex_lock(&mutex);
if(条件不满足)
pthread_cond_wait(&cond, &mutex);
//处理共享资源
pthread_mutex_unlock(&mutex);
激活线程:
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
下面写了一个例子

#include <pthread.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <iostream> using namespace std; int count = 0; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; //该函数增加count数值 void * creator(void * arg) { cout << "creator add lock" << endl; pthread_mutex_lock(&mutex); count ++; cout << "in creator count is : " << count << endl; //条件满足时发送信号 if(count > 0) { pthread_cond_signal(&cond); } cout << "creator release lock" << endl; pthread_mutex_unlock(&mutex); return NULL; } //该函数减少count数值 void * consumer(void * arg) { cout << "consumer add lock" << endl; pthread_mutex_lock(&mutex); //当条件不满足时等待 if(count <= 0) { cout << "begin wait" << endl; pthread_cond_wait(&cond,&mutex); cout << "end wait" << endl; } count --; cout << "in consumer count is " << count << endl; pthread_mutex_unlock(&mutex); cout << "consumer release lock" << endl; return NULL; } int main() { //两个线程,一个生产者线程一个消费者线程 pthread_t createthread,consumethread; pthread_create(&consumethread, NULL, consumer, NULL); sleep(2); pthread_create(&createthread, NULL, creator, NULL); //主进程等待两个线程结束 pthread_join(createthread, NULL); pthread_join(consumethread, NULL); return 0; }



void * creator(void * arg) { int i = 0; while(i<300) { i++; cout << "creator add lock" << endl; pthread_mutex_lock(&mutex); count ++; cout << "in creator count is : " << count << endl; if(count > 0) { pthread_cond_signal(&cond); } cout << "creator release lock" << endl; pthread_mutex_unlock(&mutex); } return NULL; } void * consumer(void * arg) { int i = 0; while(i < 100) { i++; cout << "consumer add lock" << endl; pthread_mutex_lock(&mutex); if(count <= 0) { cout << "begin wait" << endl; pthread_cond_wait(&cond,&mutex); cout << "end wait" << endl; } count --; cout << "in consumer count is " << count << endl; pthread_mutex_unlock(&mutex); cout << "consumer release lock" << endl; } return NULL; } int main() { pthread_t createthread[2],consumethread[3]; for(int i = 0; i < 3; i++) { pthread_create(&consumethread[i], NULL, consumer, NULL); } for(int i = 0; i < 2; i++) { pthread_create(&createthread[i], NULL, creator, NULL); } for(int i = 0; i < 2; i++) { pthread_join(createthread[i], NULL); } for(int i = 0; i < 3; i++) { pthread_join(consumethread[i], NULL); } return 0; }

截取一部分结果截图,可以看出数字是连续变动的,而且
加锁解锁内数字才变动,说明我们对锁和条件变量使用合理
pthread_cond_wait学习笔记的更多相关文章
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- PHP-自定义模板-学习笔记
1. 开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2. 整体架构图 ...
- PHP-会员登录与注册例子解析-学习笔记
1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...
- 2014年暑假c#学习笔记目录
2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...
- JAVA GUI编程学习笔记目录
2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...
- seaJs学习笔记2 – seaJs组建库的使用
原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...
- CSS学习笔记
CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...
- HTML学习笔记
HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...
- DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记
今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...
随机推荐
- 智能POS常见问题整理
智能POS预警值为小于所设的数量,H5就会变为锁定状态 智能POS查看数据库方法: 商米D1:设置-存储设备和USB-内部存储设备-浏览-winboxcash tablet.db为智能POS数据库 W ...
- c#二进制移位运算符 "<<"及">>","&","|","^"
移位运算符 & :按位与,其实与&&逻辑运算符有一致的地方: | :按位或,同样与||有类似的地方. ~:按位取反 ^:按位异或 <<:左移运算符 >> ...
- centos7个人shell编写环境
一.配置存放文件/root/wang 存放常用的文件/root/wang/shell 存放练习的shell文件/root/wang/succeed_shell 存放有用shell文件/root/bak ...
- c/c++ 网络编程 UDP up/down 网卡
网络编程 UDP up/down 网卡 在程序里动态改变网卡的状态.注意:程序运行需要root权限. 程序运行的方法: sudo ./a.out 1,关闭网卡 #include <stdio.h ...
- docker 基础
概述 起源 2013 年由 DotCloud 公司开源出来的容器管理工具 DotCloud 公司是一家 PAAS 服务提供商,从 docker 的出身也可以看出它的主要功能和方向 技术原理 开始时是基 ...
- 【Linux基础】查看硬件信息-内存和硬盘
1.使用free命令查看内存使用 (1)内存总量大小:查看Mem中的total值3697M free -m total used free shared buffers cached -/+ buf ...
- Ambari与Kerberos 集成
Kerberos 介绍 Kerberos 是一个网络认证的框架协议,其设计的初衷便是通过密钥系统为 Client 和 Server 应用程序之间提供强大的认证服务.在使用 Kerberos 认证的集群 ...
- 勇者斗恶龙 uva 11292(简单贪心)
思路:先将龙和士兵进行分别排序从小到大.然后,每次找当前最小龙的第一个大于它的骑手之后退出,开始下一个龙,重复上一次操作. #include<iostream> #include<a ...
- [LeetCode] 6. Z 字形变换
题目链接:(https://leetcode-cn.com/problems/zigzag-conversion/) 题目描述: 将一个给定字符串根据给定的行数,以从上往下.从左到右进行 Z 字形排列 ...
- Spring Boot:The field file exceeds its maximum permitted size of 1048576 bytes
错误信息:The field file exceeds its maximum permitted size of 1048576 bytes原因是因为SpringBoot内嵌tomcat默认所能上传 ...