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库,因此运用起来不是那么纯熟,例如创建生产者和消费者线程的创建没有用到合适的线程数组,希望能在以后的学习中不断地完善,不要做代码的机器,不要冗余的代码,要言简意赅!!!!!