Linux Posix线程条件变量

生产者消费者模型
.多个线程操作全局变量n,需要做成临界区(要加锁--线程锁或者信号量)
.调用函数pthread_cond_wait(&g_cond,&g_mutex)让这个线程锁在某一个条件上等待
--pthread_cond_wait()函数的本质是①:拿到锁的线程,把锁暂时丢掉(解锁)②:线程休眠,进行等待③:线程等待通知,醒来继续执行(重新获得锁)
--这个pthread_cond_wait()函数是一个原子性操作
--注意:丢掉的锁可以被生产线程获得,也可以被消费线程获得,消费者线程获取会陷入等待,生产者线程获得会发送信号,唤醒消费者
.pthread_cond_signal()生产者拿到锁,生产n,生产完成后,发送信号给消费者(唤醒消费者),生产者离开临界区
//生产者消费者模型
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h> //定义线程锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
//定义线程条件锁
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
//定义全局变量
int g_num = ; //定义消费者线程数量
#define Consume_Count 2 //定义生产者线程数量
#define Product_Count 4 //消费者线程
void *consume_run(void * arg)
{
int tnum = (int) arg;
while ()
{
//因为多线程操作一个全局变量,需要做成临界区,枷锁
pthread_mutex_lock(&mutex);
printf("消费者%d进入临界区!\n", tnum);
//因为就算消费者被唤醒,也需要重新检查g_num的值,因为pthread_cond_wait()函数丢锁之后,可能被其他消费者获得
//导致多个消费者线程都执行了pthread_cond_wait()函数陷入等待,
//因为多个消费者线程被pthread_cond_signal()唤醒,但是资源只有一个,可能已经被其他消费者使用了
//pthread_cond_wait()也有可能被其他信号唤醒
//所以需要重新判断,而不能使用if
while (g_num == )
{
printf("消费者%d开始等待!\n", tnum);
//在该线程锁上,进行条件等待
pthread_cond_wait(&cond, &mutex);
printf("消费者%d被唤醒!\n", tnum);
}
//表示已经有资源了,可以消费了
printf("消费者%d开始消费!\n", tnum);
g_num--;
//解锁
pthread_mutex_unlock(&mutex);
sleep();
}
return NULL;
} //生产者线程
void *product_run(void * arg)
{
int tnum = (int) arg;
while ()
{
//当生产者大于消费者时,可能出现生产过多的商品,需要对商品的上限做一个限制,如果商品过多,需要让生产者睡眠
//涉及到对全局变量的访问,需要加锁
printf("现有资源个数%d!\n",g_num);
pthread_mutex_lock(&mutex);
if (g_num > )
{
printf("生产者%d产品已经到达上限,进入睡眠!\n", tnum);
//如果生产产品大于上限,需要睡眠,但是睡眠前应该将锁释放.,留给消费者进行消费
pthread_mutex_unlock(&mutex);
sleep();
continue;
} else
{
printf("生产者%d生产产品!\n", tnum);
//如果生产产品小于上限,那么不需要生产者睡眠,接着生产产品
g_num++;
//发送条件信号
printf("生产者%d发送条件信号!\n", tnum);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
pthread_mutex_unlock(&mutex);
sleep();
}
return NULL;
} int main(int arg, char * args[])
{
pthread_t thrs[Consume_Count + Product_Count];
int i = ;
for (i = ; i < Consume_Count; i++)
{
if (pthread_create(&thrs[i], NULL, consume_run, (void *) i) != )
{
printf("pthread_create() failed !\n");
return -;
}
}
for (i = ; i < Product_Count; i++)
{
if (pthread_create(&thrs[i + Consume_Count], NULL, product_run,
(void *) i) != )
{
printf("pthread_create() failed !\n");
return -;
}
}
//join
for (i = ; i < Consume_Count + Product_Count; i++)
{
if (pthread_join(thrs[i], NULL) != )
{
printf("pthread_join() failed !\n");
break;
}
}
printf("进程推出了!\n");
return ;
}
Linux Posix线程条件变量的更多相关文章
- Linux Qt使用POSIX多线程条件变量、互斥锁(量)
今天团建,但是文章也要写.酒要喝好,文要写美,方为我辈程序员的全才之路.嘎嘎 之前一直在看POSIX的多线程编程,上个周末结合自己的理解,写了一个基于Qt的用条件变量同步线程的例子.故此来和大家一起分 ...
- python线程条件变量Condition(31)
对于线程与线程之间的交互我们在前面的文章已经介绍了 python 互斥锁Lock / python事件Event , 今天继续介绍一种线程交互方式 – 线程条件变量Condition. 一.线程条件变 ...
- linux Posix线程同步(条件变量) 实例
条件变量:与互斥量一起使用,暂时申请不到某资源时进入条件阻塞等待,当资源具备时线程恢复运行 应用场合:生产线程不断的生产资源,并通知产生资源的条件,消费线程在没有资源情况下进入条件等待,一直等到条件信 ...
- Linux 线程 条件变量
一:条件变量 直接上最基本的两个函数,先抓主要矛盾: //等待条件 int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex ...
- Linux posix线程库总结
由于历史原因,2.5.x以前的linux对pthreads没有提供内核级的支持,所以在linux上的pthreads实现只能采用n:1的方式,也称为库实现. 线程的实现,经历了如下发展阶段: Linu ...
- linux多线程-互斥&条件变量与同步
多线程代码问题描述 我们都知道,进程是操作系统对运行程序资源分配的基本单位,而线程是程序逻辑,调用的基本单位.在多线程的程序中,多个线程共享临界区资源,那么就会有问题: 比如 #include < ...
- posix多线程--条件变量
条件变量是用来通知共享数据状态信息的. 1.条件变量初始化两种方式:(1)静态初始化pthread_cond_t cond = PTHREAD_COND_INITIALIZER;代码示例如下: #in ...
- Linux系统编程—条件变量
条件变量是用来等待线程而不是上锁的,条件变量通常和互斥锁一起使用.条件变量之所以要和互斥锁一起使用,主要是因为互斥锁的一个明显的特点就是它只有两种状态:锁定和非锁定,而条件变量可以通过允许线程阻塞和等 ...
- linux TLS 线程本地变量
最近在写底层hook的时候, 涉及到线程安全问题, 最开始我设计的时候使用的互斥量, 但是考虑到都是底层函数,加锁会导致性能问题, 一直在思考优化方案, 后来偶然想到,java里面有线程本地变量的AP ...
随机推荐
- ASP.NET Core 中文文档 第二章 指南(4.10)检查自动生成的Detail方法和Delete方法
原文 Examining the Details and Delete methods 作者 Rick Anderson 翻译 谢炀(Kiler) 校对 许登洋(Seay).姚阿勇(Mr.Yao) 打 ...
- .Net语言 APP开发平台——Smobiler学习日志:如何实现离线声音文件上传
最前面的话:Smobiler是一个在VS环境中使用.Net语言来开发APP的开发平台,也许比Xamarin更方便 一.目标样式 我们要实现上图中的效果,需要如下的操作: 1.从工具栏上的"S ...
- Android开机动画
Android系统的开机动画可分为三个部分,kernel启动,init进程启动,android系统服务启动.这三个开机动画都是在一个叫做 帧缓冲区(frame buffer)的硬件设备上进行渲染绘制的 ...
- [连载]《C#通讯(串口和网络)框架的设计与实现》- 13.中英文版本切换设计
目 录 第十三章 中英文版本切换设计... 2 13.1 不用自带的资源文件的理由... 2 13.2 配置文件... 2 13.3 语言 ...
- Eclipse搭建Maven Prooject(终于)
今天我们一起来探讨eclipse搭建maven项目的步骤 一.建一个maven项目, 1.找到File ,点击 2.弹出窗口,再点击new 3.弹出窗口,点击other 4.输入maven,找到mav ...
- freemarker页面中文乱码
一.前言 简单的记录freemarker遇到的错误问题:ftl页面中文乱码 由于freemarker整合在ssm框架中,所以笔者直接贴配置代码 <beans xmlns="http:/ ...
- iOS 汉字的拼音
获取汉字的拼音 #import <Foundation/Foundation.h> @interface NSString (Utils) /** * 汉字的拼音 * * @return ...
- CentOS7 查看IP、Gateway、DNS、Hostname
1.查看IP# ip addr 2.查看路由# ip route 3.查看DNS# cat /etc/resolv.conf 4.查看主机名# hostname
- 利用私有的库MobileCoreServices检测正在安装的应用
利用的私有库检测正在安装的app 分为两步:第一,通过placeholderApplications获得所有的正在安装的app的信息 第二,遍历正在安装的app的信息,根据名称获得你想检测的app是否 ...
- iOS从零开始学习直播之音频1.播放本地音频文件
现在直播越来越火,俨然已经成为了下一个红海.作为一个资深码农(我只喜欢这样称呼自己,不喜欢别人这样称呼我),我必须赶上时代的潮流,开始研究视频直播.发现视屏直播类的文章上来就讲拉流.推流.采集.美 ...