生产者消费者模型
.多个线程操作全局变量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线程条件变量的更多相关文章

  1. Linux Qt使用POSIX多线程条件变量、互斥锁(量)

    今天团建,但是文章也要写.酒要喝好,文要写美,方为我辈程序员的全才之路.嘎嘎 之前一直在看POSIX的多线程编程,上个周末结合自己的理解,写了一个基于Qt的用条件变量同步线程的例子.故此来和大家一起分 ...

  2. python线程条件变量Condition(31)

    对于线程与线程之间的交互我们在前面的文章已经介绍了 python 互斥锁Lock / python事件Event , 今天继续介绍一种线程交互方式 – 线程条件变量Condition. 一.线程条件变 ...

  3. linux Posix线程同步(条件变量) 实例

    条件变量:与互斥量一起使用,暂时申请不到某资源时进入条件阻塞等待,当资源具备时线程恢复运行 应用场合:生产线程不断的生产资源,并通知产生资源的条件,消费线程在没有资源情况下进入条件等待,一直等到条件信 ...

  4. Linux 线程 条件变量

    一:条件变量 直接上最基本的两个函数,先抓主要矛盾: //等待条件 int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex ...

  5. Linux posix线程库总结

    由于历史原因,2.5.x以前的linux对pthreads没有提供内核级的支持,所以在linux上的pthreads实现只能采用n:1的方式,也称为库实现. 线程的实现,经历了如下发展阶段: Linu ...

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

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

  7. posix多线程--条件变量

    条件变量是用来通知共享数据状态信息的. 1.条件变量初始化两种方式:(1)静态初始化pthread_cond_t cond = PTHREAD_COND_INITIALIZER;代码示例如下: #in ...

  8. Linux系统编程—条件变量

    条件变量是用来等待线程而不是上锁的,条件变量通常和互斥锁一起使用.条件变量之所以要和互斥锁一起使用,主要是因为互斥锁的一个明显的特点就是它只有两种状态:锁定和非锁定,而条件变量可以通过允许线程阻塞和等 ...

  9. linux TLS 线程本地变量

    最近在写底层hook的时候, 涉及到线程安全问题, 最开始我设计的时候使用的互斥量, 但是考虑到都是底层函数,加锁会导致性能问题, 一直在思考优化方案, 后来偶然想到,java里面有线程本地变量的AP ...

随机推荐

  1. 代码的坏味道(9)——异曲同工的类(Alternative Classes with Different Interfaces)

    坏味道--异曲同工的类(Alternative Classes with Different Interfaces) 特征 两个类中有着不同的函数,却在做着同一件事. 问题原因 这种情况往往是因为:创 ...

  2. Windows Phone 8.1又有什么新花样

    今年微软新任CEO提出了“Mobile First and Cloud First”的发展战略,随着微软Mobile First战略的实行,开发者是时候重视Windows Phone了.你可能不相信, ...

  3. JavaScript 跨域漫游

    前言: 最近在公司做了几个项目都涉及到了iframe,也就是在这些iframe多次嵌套的项目中,我发现之前对iframe的认识还是比较不足的,所以就静下心来,好好整理总结了iframe的相关知识:&l ...

  4. 【转载】保哥 釐清 CLR、.NET、C#、Visual Studio、ASP.NET 各版本之間的關係

    我常常不仅仅逛 博客园,还会去找国外,特别是台湾的技术部落格,发现好的文章,我便会收录,今天我转载或者全文复制,在Google 博客园,一位叫保哥, 釐清 CLR..NET.C#.Visual Stu ...

  5. shiro的使用1 简单的认证

    最近在重构,有空学了一个简单的安全框架shiro,资料比较少,在百度和google上能搜到的中文我看过了,剩下的时间有空会研究下官网的文章和查看下源码, 简单的分享一些学习过程: 1,简单的一些概念上 ...

  6. django+mysql学习笔记

    这段时间在学习mysql+django的知识点.借此记录以下学习过程遇到的坑以及心得. 使用的工具是navicat for mysql python 2.7.12 mysql-python 1.2.3 ...

  7. java基础思维导图

    如果图片看不清楚的可以把图片另存为桌面放大看哈

  8. KMP算法

    KMP算法是字符串模式匹配当中最经典的算法,原来大二学数据结构的有讲,但是当时只是记住了原理,但不知道代码实现,今天终于是完成了KMP的代码实现.原理KMP的原理其实很简单,给定一个字符串和一个模式串 ...

  9. Flexible 弹性盒子模型之flex

    实例 让所有弹性盒模型对象的子元素都有相同的长度,忽略它们内部的内容: #main div { flex:1; } 复制 效果预览 浏览器支持 表格中的数字表示支持该属性的第一个浏览器的版本号. 紧跟 ...

  10. js判断窗体或容器滚动条到底部

    NO1---jquery判断窗体滚动条到底部 $(window).scroll(function () {if ($(window).scrollTop() >= $(document).hei ...