您的位置:首页 > 其它

操作系统同步生产者消费者问题

2014-01-09 22:46 351 查看
Linux进程创建
一、设计目的

通过模拟操作者生产者经典问题的实现,深入理解操作系统中多线程同步法的理论知识, 加深对教材中的重要算法的理解。同时通过编程实现这些算法,更好地掌握操作系统的原理及实现方法,提高综合运用各专业课知识的能力。

二、设计要求

初始条件:

1. 操作系统:Linux

2. 程序设计语言:C语言

3. 其中(生产者)从外设获取数据进行生产

另外(消费者)消费后进行输出,并存储输出结果。

技术要求:

1)为每个生产者/消费者产生一个线程,设计正确的同步算法

2)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的当前全部内容、当前指针位置和生产者/消费者线程的自定义标识符。

3)生产者和消费者各有30个;

4)多个生产者或多个消费者之间须共享对缓冲区进行操作的函数代码。

三、设计说明

一 信号量

PV操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下:

P(S):①将信号量S的值减1,即S=S-1;

②如果S?0,则该进程继续执行;否则该进程置为等待状态,排入等待队列。

V(S):①将信号量S的值加1,即S=S+1;

②如果S>0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。

PV操作的意义:我们用信号量及PV操作来实现进程的同步和互斥。PV操作属于进程的低级通信。

什么是信号量?信号量(semaphore)的数据结构为一个值和一个指针,指针指向等待该信 号量的下一个进程。信号量的值与相应资源的使用情况有关。当它的值大于0时,表示当前可用资源的数量;当它的值小于0时,其绝对值表示等待使用该资源的进 程个数。注意,信号量的值仅能由PV操作来改变。

一般来说,信号量S?0时,S表示可用资源的数量。执行一次P操作意味着请求分配一个单位资源,因此S的值减1;当S<0时,表示已经没有可用资 源,请求者必须等待别的进程释放该类资源,它才能运行下去。而执行一个V操作意味着释放一个单位资源,因此S的值加1;若S?0,表示有某些进程正在等待 该资源,因此要唤醒一个等待状态的进程,使之运行下去。

利用信号量和PV操作实现进程互斥的一般模型是:

进程P1 进程P2 …… 进程Pn

…… …… ……

P(S); P(S); P(S);

临界区; 临界区; 临界区;

V(S); V(S); V(S);

…… …… …… ……

其中信号量S用于互斥,初值为1。

使用PV操作实现进程互斥时应该注意的是:

(1)每个程序中用户实现互斥的P、V操作必须成对出现,先做P操作,进临界区,后做V操作,出临界区。若有多个分支,要认真检查其成对性。

(2)P、V操作应分别紧靠临界区的头尾部,临界区的代码应尽可能短,不能有死循环。

(3)互斥信号量的初值一般为1。

利用信号量和PV操作实现进程同步

PV操作是典型的同步机制之一。用一个信号量与一个消息联系起来,当信号量的值为0时,表示期望的消息尚未产生;当信号量的值非0时,表示期望的消息已经存在。用PV操作实现进程同步时,调用P操作测试消息是否到达,调用V操作发送消息。

使用PV操作实现进程同步时应该注意的是:

(1)分析进程间的制约关系,确定信号量种类。在保持进程间有正确的同步关系情况下,哪个进程先执行,哪些进程后执行,彼此间通过什么资源(信号量)进行协调,从而明确要设置哪些信号量。

(2)信号量的初值与相应资源的数量有关,也与P、V操作在程序代码中出现的位置有关。

(3)同一信号量的P、V操作要成对出现,但它们分别在不同的进程代码中。

(3)一组生产者,一组消费者,公用n个环形缓冲区

在这个问题中,不仅生产者与消费者之间要同步,而且各个生产者之间、各个消费者之间还必须互斥地访问缓冲区。

定义四个信号量:

empty——表示缓冲区是否为空,初值为20。

full——表示缓冲区中是否为满,初值为0。

mutex——生产者之间的互斥信号量,初值为null。

设缓冲区的编号为1~n-1,定义两个指针in和out,分别是生产者进程和消费者进程使用的指针,指向下一个可用的缓冲区。

生产者进程

do{

生产一个产品;

P(empty);

P(mutex1);

产品送往buffer(in);

in=(in+1)mod n;

V(mutex1);

V(full);

}while(1)

消费者进程

do{

P(full)

P(mutex2);

从buffer(out)中取出产品;

out=(out+1)mod n;

V(mutex2);

V(empty);

消费该产品;

}while(1)

需要注意的是无论在生产者进程中还是在消费者进程中,两个P操作的次序不能颠倒。应先执行同步信号量的P操作,然后再执行互斥信号量的P操作,否则可能造成进程死锁。



3 开发环境与工具

系统平台:LINUX环境

实现语言:C语言

开发工具:VI编辑器

4 概要设计

程序模块说明

生产者(Producer)模块

生产者线程向一缓冲区中写入数据,且写入缓冲区的数目不能超过缓冲区容量。当生产者产生出数据,需要将其存入缓冲区之前,首先检查缓冲区中是否有“空”存储单元,若缓冲区存储单元全部用完,则生产者必须阻塞等待,直到消费者取走一个存储单元的数据,唤醒它。若缓冲区内有“空”存储单元,生产者需要判断此时是否有别的生产者或消费者正在使用缓冲区,若是有,则阻塞等待,否则,获得缓冲区的使用权,将数据存入缓冲区,释放缓冲区的使用权。

消费者(Consumer)模块

消费者线程从缓冲区中读取数据,且消费者读取的数目不能超过生产者写入的数目。消费者取数据之前,首先检查缓冲区中是否存在装有数据的存储单元,若缓冲区为“空”,则阻塞等待,否则,判断缓冲区是否正在被使用,若正被使用,若正被使用,则阻塞等待,否则,获得缓冲区的使用权,进入缓冲区取数据,释放缓冲区的使用权。





四、运行结果及分析







五、总结

用多线程同步互斥方法解决生产者-消费者问题

本次课程设计, 在做的过程中,我体会到了自己的不足,很多地方都不懂,但是我觉得在这个阶段对一些比较深的东西也不一定要处处都弄懂,有时候子要自己跟着做,会用,久而久之也会随着经验的加深而慢慢弄懂,这虽然是一种不求甚解的态度,但在初级编程中往往是很有用的。 本次课程设计的程序更具要求定义了20个缓冲区,基本上能顺利解决生产者消费者问题,但也存在很多不足之处。因为程序都是根据别人的来





源程序代码



#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#include <semaphore.h>

#include <unistd.h> //POSIX API

#define BUFFER_SIZE 20//20个缓冲区

#define MES 30 //每个生产者生产的30个消息

int consumenum = 0;

int buffer[20]= {0};

sem_t empty;//表示缓冲区是否为空,初值为20

sem_t full;//表示缓冲区中是否为满,初值为0

pthread_mutex_t mutex; //for mutual exclusion进程信号量

int in=0; //point to the next free positon

int out=0; //point to the first full positon

//把所有的缓冲区输出到屏幕上

void printAll()

{

int i;

for(i=0; i<20; i++)

printf("%d ",buffer[i]);

printf("\n");

printf("current producer pointer:%d\n",in);

printf("current consumer pointer:%d\n",out);

}

//生产者线程 1

void producer1(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 2

void producer2(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 3

void producer3(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 4

void producer4(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 5

void producer5(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 6

void producer6(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 7

void producer7(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 8

void producer8(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 9

void producer9(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 10

void producer10(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 11

void producer11(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 12

void producer12(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 13

void producer13(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 14

void producer14(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 15

void producer15(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 16

void producer16(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 17

void producer17(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 18

void producer18(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 19

void producer19(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 20

void producer20(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 21

void producer21(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 22

void producer22(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 23

void producer23(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 24

void producer24(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 25

void producer25(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 26

void producer26(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 27

void producer27(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 28

void producer28(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 29

void producer29(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count > MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//生产者线程 30

void producer30(char *arg)

{

int count = 0;

do

{

sem_wait(&empty); //空缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁

//往Buffer中放入产品

++count;

if(count >= MES) break;

buffer[in]=in+1;

in=(in+1)%BUFFER_SIZE;//放入指针调整,为下次送出做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&full); //满缓冲区加1,即当公共资源增加时,调用函数sem_post()增加信号量

sleep(1);

}

while(count <= MES);

}

//消费者线程 1

void consumer1(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

++consumenum;

if(consumenum >= MES * 30) goto loop;

buffer[out]=0;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 2

void consumer2(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 3

void consumer3(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 4

void consumer4(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 5

void consumer5(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 6

void consumer6(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 7

void consumer7(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 8

void consumer8(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 9

void consumer9(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 10

void consumer10(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 11

void consumer11(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 12

void consumer12(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 13

void consumer13(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 14

void consumer14(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 15

void consumer15(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 16

void consumer16(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 17

void consumer17(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 18

void consumer18(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 19

void consumer19(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 20

void consumer20(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 21

void consumer21(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 22

void consumer22(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 23

void consumer23(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 24

void consumer24(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 25

void consumer25(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 26

void consumer26(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 27

void consumer27(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 28

void consumer28(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 29

void consumer29(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//消费者线程 30

void consumer30(char *arg)

{

do

{

sem_wait(&full); //满缓冲区减1

pthread_mutex_lock(&mutex); //信号量上锁//从Buffer中取出产品

buffer[out]=0;

++consumenum;

if(consumenum >= MES * 30) goto loop;

out=(out+1)%BUFFER_SIZE;//取指针调整,为下次取做准备

printf("%s\n",arg);

printAll();

pthread_mutex_unlock(&mutex); //信号量解锁

sem_post(&empty); //空缓冲区加1

sleep(2);

}

while(1);

loop: exit(0);

}

//主线程

int main()

{

//创建进程

pthread_t producer_1,producer_2,producer_3,producer_4,producer_5,producer_6,producer_7,producer_8,producer_9,producer_10,producer_11,producer_12,producer_13,producer_14,producer_15,producer_16,producer_17,producer_18,producer_19,producer_20,producer_21,producer_22,producer_23,producer_24,producer_25,producer_26,producer_27,producer_28,producer_29,producer_30;

pthread_t consumer_1,consumer_2,consumer_3,consumer_4,consumer_5,consumer_6,consumer_7,consumer_8,consumer_9,consumer_10,consumer_11,consumer_12,consumer_13,consumer_14,consumer_15,consumer_16,consumer_17,consumer_18,consumer_19,consumer_20,consumer_21,consumer_22,consumer_23,consumer_24,consumer_25,consumer_26,consumer_27,consumer_28,consumer_29,consumer_30;

void *retval;

pthread_mutex_init(&mutex,NULL);// /* 用默认属性初始化一个互斥变量mutex// 初始化信号量

sem_init(&full,0,0);

sem_init(&empty,0,BUFFER_SIZE);

//pthread_create函数用来创建生产者和消费者进程,其四个参数分别表示为进程、NULL、进程要执行的函数、执行函数时的参数

pthread_create(&producer_1,NULL,(void*)producer1,"producer1:");

pthread_create(&consumer_1,NULL,(void*)consumer1,"consumer1:");

pthread_create(&producer_2,NULL,(void*)producer2,"producer2:");

pthread_create(&consumer_2,NULL,(void*)consumer2,"consumer2:");

pthread_create(&producer_3,NULL,(void*)producer3,"producer3:");

pthread_create(&consumer_3,NULL,(void*)consumer3,"consumer3:");

pthread_create(&producer_4,NULL,(void*)producer4,"producer4:");

pthread_create(&consumer_4,NULL,(void*)consumer4,"consumer4:");

pthread_create(&producer_5,NULL,(void*)producer5,"producer5:");

pthread_create(&consumer_5,NULL,(void*)consumer5,"consumer5:");

pthread_create(&producer_6,NULL,(void*)producer6,"producer6:");

pthread_create(&consumer_6,NULL,(void*)consumer6,"consumer6:");

pthread_create(&producer_7,NULL,(void*)producer7,"producer7:");

pthread_create(&consumer_7,NULL,(void*)consumer7,"consumer7:");

pthread_create(&producer_8,NULL,(void*)producer8,"producer8:");

pthread_create(&consumer_8,NULL,(void*)consumer8,"consumer8:");

pthread_create(&producer_9,NULL,(void*)producer9,"producer9:");

pthread_create(&consumer_9,NULL,(void*)consumer9,"consumer9:");

pthread_create(&producer_10,NULL,(void*)producer10,"producer10:");

pthread_create(&consumer_10,NULL,(void*)consumer10,"consumer10:");

pthread_create(&producer_11,NULL,(void*)producer11,"producer11:");

pthread_create(&consumer_11,NULL,(void*)consumer11,"consumer11:");

pthread_create(&producer_12,NULL,(void*)producer12,"producer12:");

pthread_create(&consumer_12,NULL,(void*)consumer12,"consumer12:");

pthread_create(&producer_13,NULL,(void*)producer13,"producer13:");

pthread_create(&consumer_13,NULL,(void*)consumer13,"consumer13:");

pthread_create(&producer_14,NULL,(void*)producer14,"producer14:");

pthread_create(&consumer_14,NULL,(void*)consumer14,"consumer14:");

pthread_create(&producer_15,NULL,(void*)producer15,"producer15:");

pthread_create(&consumer_15,NULL,(void*)consumer15,"consumer15:");

pthread_create(&producer_16,NULL,(void*)producer16,"producer16:");

pthread_create(&consumer_16,NULL,(void*)consumer16,"consumer16:");

pthread_create(&producer_17,NULL,(void*)producer17,"producer17:");

pthread_create(&consumer_17,NULL,(void*)consumer17,"consumer17:");

pthread_create(&producer_18,NULL,(void*)producer18,"producer18:");

pthread_create(&consumer_18,NULL,(void*)consumer18,"consumer18:");

pthread_create(&producer_19,NULL,(void*)producer19,"producer19:");

pthread_create(&consumer_19,NULL,(void*)consumer19,"consumer19:");

pthread_create(&producer_20,NULL,(void*)producer20,"producer20:");

pthread_create(&consumer_20,NULL,(void*)consumer20,"consumer20:");

pthread_create(&producer_21,NULL,(void*)producer21,"producer21:");

pthread_create(&consumer_21,NULL,(void*)consumer21,"consumer21:");

pthread_create(&producer_22,NULL,(void*)producer22,"producer22:");

pthread_create(&consumer_22,NULL,(void*)consumer22,"consumer22:");

pthread_create(&producer_23,NULL,(void*)producer23,"producer23:");

pthread_create(&consumer_23,NULL,(void*)consumer23,"consumer23:");

pthread_create(&producer_24,NULL,(void*)producer24,"producer24:");

pthread_create(&consumer_24,NULL,(void*)consumer24,"consumer24:");

pthread_create(&producer_25,NULL,(void*)producer25,"producer25:");

pthread_create(&consumer_25,NULL,(void*)consumer25,"consumer25:");

pthread_create(&producer_26,NULL,(void*)producer26,"producer26:");

pthread_create(&consumer_26,NULL,(void*)consumer26,"consumer26:");

pthread_create(&producer_27,NULL,(void*)producer27,"producer27:");

pthread_create(&consumer_27,NULL,(void*)consumer27,"consumer27:");

pthread_create(&producer_28,NULL,(void*)producer28,"producer28:");

pthread_create(&consumer_28,NULL,(void*)consumer28,"consumer28:");

pthread_create(&producer_29,NULL,(void*)producer29,"producer29:");

pthread_create(&consumer_29,NULL,(void*)consumer29,"consumer29:");

pthread_create(&producer_30,NULL,(void*)producer30,"producer30:");

pthread_create(&consumer_30,NULL,(void*)consumer30,"consumer30:");

//pthread_join用来表示等待线程的结束,表示producer1,producer2,producer3, producer4, consumer1,consumer2,consumer3 consumer4执行完毕之前主程序必须等待

pthread_join(producer_1, &retval);

pthread_join(consumer_1, &retval);

pthread_join(producer_2, &retval);

pthread_join(consumer_2, &retval);

pthread_join(producer_3, &retval);

pthread_join(consumer_3, &retval);

pthread_join(producer_4, &retval);

pthread_join(consumer_4, &retval);

pthread_join(producer_5, &retval);

pthread_join(consumer_5, &retval);

pthread_join(producer_6, &retval);

pthread_join(consumer_6, &retval);

pthread_join(producer_7, &retval);

pthread_join(consumer_7, &retval);

pthread_join(producer_8, &retval);

pthread_join(consumer_8, &retval);

pthread_join(producer_9, &retval);

pthread_join(consumer_9, &retval);

pthread_join(producer_10, &retval);

pthread_join(consumer_10, &retval);

pthread_join(producer_11, &retval);

pthread_join(consumer_11, &retval);

pthread_join(producer_12, &retval);

pthread_join(consumer_12, &retval);

pthread_join(producer_13, &retval);

pthread_join(consumer_13, &retval);

pthread_join(producer_14, &retval);

pthread_join(consumer_14, &retval);

pthread_join(producer_15, &retval);

pthread_join(consumer_15, &retval);

pthread_join(producer_16, &retval);

pthread_join(consumer_16, &retval);

pthread_join(producer_17, &retval);

pthread_join(consumer_17, &retval);

pthread_join(producer_18, &retval);

pthread_join(consumer_18, &retval);

pthread_join(producer_19, &retval);

pthread_join(consumer_19, &retval);

pthread_join(producer_20, &retval);

pthread_join(consumer_20, &retval);

pthread_join(producer_21, &retval);

pthread_join(consumer_21, &retval);

pthread_join(producer_22, &retval);

pthread_join(consumer_22, &retval);

pthread_join(producer_23, &retval);

pthread_join(consumer_23, &retval);

pthread_join(producer_24, &retval);

pthread_join(consumer_24, &retval);

pthread_join(producer_25, &retval);

pthread_join(consumer_25, &retval);

pthread_join(producer_26, &retval);

pthread_join(consumer_26, &retval);

pthread_join(producer_27, &retval);

pthread_join(consumer_27, &retval);

pthread_join(producer_28, &retval);

pthread_join(consumer_28, &retval);

pthread_join(producer_29, &retval);

pthread_join(consumer_29, &retval);

pthread_join(producer_30, &retval);

pthread_join(consumer_30, &retval);

return 0;

}



总结:

通过生产者消费者线程的练习,使我了解了线程同步互斥之间的区别,并且对信号量的运用更加纯熟。本程序用linux的gcc编译器运行的,使我对linux操作系统的C语言编程更加了解,由于第一次使用linux的POSIX库,因此运用起来不是那么纯熟,例如创建生产者和消费者线程的创建没有用到合适的线程数组,希望能在以后的学习中不断地完善,不要做代码的机器,不要冗余的代码,要言简意赅!!!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: