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 ...
随机推荐
- Oracle数据库升级(10.2.0.4->11.2.0.4)
环境: RHEL5.4 + Oracle 10.2.0.4 目的: 在本机将数据库升级到11.2.0.4 之前总结的Oracle数据库异机升级:http://www.cnblogs.com/jyzha ...
- 强大的图片加载框架Fresco的使用
前面在卓新科技有限公司实习的时候,在自己的爱吖头条APP中,在图片异步加载的时候和ListView的滑动中,总会出现卡顿,这是因为图片的缓存做的不是足够到位,在项目监理的帮助下,有使用Xutils框架 ...
- 你真的会玩SQL吗?简单的数据修改
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- 行为驱动开发(BDD)实践示例
引言 BDD是对TDD理念的扩展.BDD强调有利害关系的技术团体和非技术团队都要参与到软件开发过程中.可以把它看成一种强调团体间合作的敏捷方法.大多数采用某种敏捷方法的团队最终都会遵循BDD的许多原则 ...
- PID控制
PID解释: 位置式: 可以看出,比例部分只与当前的偏差有关,而积分部分则是系统过去所有偏差的累积.位置式PI调节器的结构清晰,P和I两部分作用分明,参数调整简单明了.但直观上看,要计算第拍 ...
- 手把手教从零开始在GitHub上使用Hexo搭建博客教程(一)-附GitHub注册及配置
前言 有朋友问了我关于博客系统搭建相关的问题,由于是做开发相关的工作,我给他推荐的是使用github的gh-pages服务搭建个人博客. 推荐理由: 免费:github提供gh-pages服务是免费的 ...
- 你所不知道的linq
问题的提出 昨天在qq群问了一个linq的问题被人鄙视了.题目大概类似于 var reuslt=from s in new List<string>() select s; 问from.. ...
- 移动端API接口优化的术和结果
最近一直在忙工作的事情,所以文章写得有些少. 有3-5篇文章都是写到一半然后被别的事情给打断了,所以,我得找个时间好好补补. 最近一直在关注移动端接口API的可用性问题,在移动时代这个做这个优化能产生 ...
- bzoj2693--莫比乌斯反演+积性函数线性筛
推导: 设d=gcd(i,j) 利用莫比乌斯函数的性质 令sum(x,y)=(x*(x+1)/2)*(y*(y+1)/2) 令T=d*t 设f(T)= T可以分块.又由于μ是积性函数,积性函数的约束和 ...
- POI操作Excel
POI和Excel简介 JAVA中操作Excel的有两种比较主流的工具包: JXL 和 POI .jxl 只能操作Excel 95, 97, 2000也即以.xls为后缀的excel.而poi可以操作 ...