思路

生产者和消费者(互斥与同步)。资源用队列模拟(要上锁,一个时间只能有一个线程操作队列)。

m个生产者。拿到锁,且产品不满,才能生产。当产品满,则等待,等待消费者唤醒。当产品由空到不空,通知消费者。
n个消费者。拿到锁,且有产品,才能消费。当产品空,则等待,等待生产者唤醒。当产品由满到不满,通知生产者。
   
生产者条件:队列不满
消费者条件:队列不空
因此有两个条件变量。

代码

/*************************************************************************
> File Name: main.c
> Author: KrisChou
> Mail:zhoujx0219@163.com
> Created Time: Tue 26 Aug 2014 02:55:01 PM CST
************************************************************************/ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#define CNT 20 /* 最多生产20个产品 */ /* 用队列模拟车间 */
/* front和tail初始化均为0,tail是下一个资源生成的下一个数组空间下标 */
typedef struct tag
{
int s_arr[CNT + 1] ; /* 生产20个产品,必须有21个空间,因为如果空间都装满产品,无法区别队列满和队列空 */
int s_front ;
int s_tail ;
}QUEUE,*pQUEUE ;
QUEUE my_que ;
/* 资源为空 */
int que_empty(pQUEUE pq)
{
return pq ->s_front == pq -> s_tail ;
}
/* 资源为满 */
int que_full(pQUEUE pq)
{
return (pq -> s_tail + 1)% (CNT+1) == pq -> s_front ;
}
int que_cnt(pQUEUE pq)
{
return (pq -> s_tail - pq ->s_front + CNT + 1)% (CNT + 1) ;
}
pthread_mutex_t mutex ;
pthread_cond_t cond_pro, cond_con ; void* pro_handler(void* arg)
{
pthread_detach(pthread_self());
while(1)
{
pthread_mutex_lock(&mutex) ;
while(que_full(&my_que))
{
pthread_cond_wait(&cond_pro, &mutex);
}
my_que.s_arr[my_que.s_tail ] = rand() % 1000 ;
my_que.s_tail = (my_que.s_tail + 1)% (CNT + 1) ;
if(que_cnt(&my_que) == 1)
{
pthread_cond_broadcast(&cond_con);
}
printf("produce a product, total num : %d \n", que_cnt(&my_que));
pthread_mutex_unlock(&mutex);
sleep(rand()%3 + 1);
}
}
void* con_handler(void* arg)
{
pthread_detach(pthread_self());
while(1)
{
pthread_mutex_lock(&mutex);
while(que_empty(&my_que))
{
pthread_cond_wait(&cond_con, &mutex);
}
my_que.s_front = (my_que.s_front + 1) % (CNT + 1) ;
if(que_cnt(&my_que) == CNT - 1)
{
/*由于我们的主线程是等消费者线程创建完之后,再创建生产者线程,
因此一开始所有消费者线程都会挂起,在条件变量cond_pro的队列里排队
因此需要用broadcast通知所有消费者线程。
不然一次就通知一个生产者线程,就此消费者线程会抢锁。
当然,如果一开始主线程先创建生产者线程,再创建消费者线程,
由于生产者线程不会全部阻塞,因此可以使用signal来唤醒一个 */
pthread_cond_broadcast(&cond_pro);
}
printf("consume a product, total num: %d \n", que_cnt(&my_que));
pthread_mutex_unlock(&mutex);
sleep(rand()%3 + 1);
} }
int main(int argc, char* argv[])//exe pro_num con_num
{
int con_cnt , pro_cnt ;
my_que.s_front = 0 ;
my_que.s_tail = 0 ;
pro_cnt = atoi(argv[1]) ;
con_cnt = atoi(argv[2]) ;
srand(getpid());
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond_pro, NULL);
pthread_cond_init(&cond_con, NULL);
pthread_t* arr = (pthread_t*)calloc(con_cnt + pro_cnt, sizeof(pthread_t));
int index = 0 ;
while(con_cnt > 0)
{
pthread_create(arr + index , NULL, con_handler, NULL);
index ++ ;
con_cnt -- ;
}
sleep(5);
while(pro_cnt > 0)
{
pthread_create(arr + index , NULL, pro_handler, NULL);
index ++ ;
pro_cnt -- ;
}
while(1) ;
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond_pro);
pthread_cond_destroy(&cond_con);
return 0 ;
}
 Makefile
main:main.c
gcc -o $@ $< -lpthread

Linux多线程之同步2 —— 生产者消费者模型的更多相关文章

  1. Linux同步互斥(Peterson算法,生产者消费者模型)

    同步 两个或两个以上随时间变化的量在变化过程中保持一定的相对关系. 互斥 对一组并发进程,一次只有一个进程能够访问一个给定的资源或执行一个给定的功能. 互斥技术可以用于解决诸如资源争用之类的冲突,还可 ...

  2. 进程,线程,GIL,Python多线程,生产者消费者模型都是什么鬼

    1. 操作系统基本知识,进程,线程 CPU是计算机的核心,承担了所有的计算任务: 操作系统是计算机的管理者,它负责任务的调度.资源的分配和管理,统领整个计算机硬件:那么操作系统是如何进行任务调度的呢? ...

  3. 多道技术 进程 线程 协程 GIL锁 同步异步 高并发的解决方案 生产者消费者模型

    本文基本内容 多道技术 进程 线程 协程 并发 多线程 多进程 线程池 进程池 GIL锁 互斥锁 网络IO 同步 异步等 实现高并发的几种方式 协程:单线程实现并发 一 多道技术 产生背景 所有程序串 ...

  4. Java多线程之~~~使用Exchanger在线程之间交换数据[这个结合多线程并行会有解决很多问题]生产者消费者模型

    http://blog.csdn.net/a352193394/article/details/39503857  Java多线程之~~~使用Exchanger在线程之间交换数据[这个结合多线程并行会 ...

  5. python并发编程之多进程(二):互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型

    一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终 ...

  6. python开发进程:互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型

    一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终 ...

  7. java多线程:线程间通信——生产者消费者模型

    一.背景 && 定义 多线程环境下,只要有并发问题,就要保证数据的安全性,一般指的是通过 synchronized 来进行同步. 另一个问题是,多个线程之间如何协作呢? 我们看一个仓库 ...

  8. java 线程池、多线程实战(生产者消费者模型,1 vs 10) 附案例源码

    导读 前二天写了一篇<Java 多线程并发编程>点我直达,放国庆,在家闲着没事,继续写剩下的东西,开干! 线程池 为什么要使用线程池 例如web服务器.数据库服务器.文件服务器或邮件服务器 ...

  9. Java多线程15:Queue、BlockingQueue以及利用BlockingQueue实现生产者/消费者模型

    Queue是什么 队列,是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的.无论使用哪种排序方式,队列的头都是调用remove()或poll()移 ...

随机推荐

  1. jQuery无缝滚动插件

    插件代码 ;(function ($) { // jQuery marquee 插件 $.fn.marquee = function (options) { // 默认设置 var defaults ...

  2. PHY

    Linux 下smi/mdio总线通信 韩大卫@吉林师范大学 下面代码描述了在用户层访问smi/mdio总线, 读写phy芯片寄存器的通用代码.Linux内核2.6以上通用. 将下面代码编译后,将可执 ...

  3. notepad++ erlang开发环境设置

    初学erlang 网上有使用eclipse的,有使用emacs的,尝试了一下, 感觉太麻烦,来试试notepad++吧. 有什么新使用方法会再更新上来,for you for me. 1.语法高亮: ...

  4. ArcGIS Server10.2服务启动不了之http://localhost:6080/arcgis/manager无法打开之arcMap 无法打开6080admin问题解决之路

    遇到的问题:在services.msc中可以正常启动arcGIS server ,但是过几秒种服务就自动关闭, 而且manager打不开, 各种方法都试过了,什么关闭杀毒软件,更改服务配置文件,更改a ...

  5. P1179: [Apio2009]Atm

    缩点+spfa最短路,因为最终不可能有环,所以直接spfa. ; type node=record f,t:longint; end; var n,m,s,i,j,ans,cnt,num,u,x,dg ...

  6. 从浅到深掌握Oracle的锁

      1.分别模拟insert,update和delete造成阻塞的示例,并对v$lock中的相应的信息进行说明,给 出SQL演示. Insert示例 会话:SQL> select * from ...

  7. PBOC2.0与PBOC3.0的区别

    2013年2月,中国人民银行发布了<中国金融集成电路(IC)卡规范(V3.0)>(以下简称PBOC3.0),PBOC3.0是在中国人民银行2005年颁布的<中国金融集成电路(IC)卡 ...

  8. CentOS7下通过rpm方式安装MySQL及插入中文问题解决 [原创]

    一 CentOS下通过rpm方式安装MySQL CentOS版本:CentOS-7 MySQL版本:MySQL-5.6.22 在网上搜了一下,Linux下安装MYSQL有三种方式: 1) 通过yum命 ...

  9. 18、ESC/POS指令集在android设备上使用实例(通过socket)

    网上关于通过android来操作打印机的例子太少了,为了方便更多的开发同仁,将近日所学分享一下. 我这边是通过android设备通过无线来对打印机(佳博58mm热敏式-58130iC)操作,实现餐厅小 ...

  10. 【BZOJ】【1049】【HAOI2006】数字序列

    DP 第一问比较水……a[i]-=i 以后就变成最长不下降子序列问题了,第二问这个结论好神奇,考试的时候怎么破?大胆猜想,不用证明?TAT 题解:http://pan.baidu.com/share/ ...