本文代码内容为对此博客下代码的修改和解释: 点此查看大佬博客. 作为初学者,对大佬每行代码的具体功能写了自己所理解的注释,如有差错,还望指正。
一.实验目的
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201117220331909.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNDE3MDAz,size_16,color_FFFFFF,t_70#pic_center)
二.实验内容
1.通过pthread_t来创建线程对象,通过pthread_create来实现对线程的执行创建。 2.创建code.c文件来实现对互斥的实现。(已对所有代码注释解释)
//code.c
#include
#include
#include
#include
#define true 1
//生产者ID
int product_id = 0;
//消费者ID
int consumer_id = 0;
//缓冲区大小
int N;
//生产者数目
int producerNum;
//消费者数目
int consumerNum;
//类型定义 int型 信号
typedef int semaphore;
//类型定义 int型 商品
typedef int item;
//定义 商品类型的缓冲数组
item* buffer;
//头索引,输入索引,头指针,用于标识生产者的输入位置
int in = 0;
//尾索引,输出索引,尾指针,用于标识消费者的输出位置
int out = 0;
//产品数目
int proCount = 0;
//mutex 互斥变量,empty 缓冲区空白大小,full 缓冲区非空白大小,proCmutex 生产者互斥变量
semaphore mutex = 1, empty , full = 0, proCmutex = 1;
//pthread_create函数创建进程时,需要一个指针类型的函数作为参数,所以定义为指针类型。
//producer与consumer作为线程的执行体。
void * producer(void * a){
int id = ++product_id;
while(true){
int flag = 0;
//如果缓冲区已满报错
while(empty printf("生产者%d生产阻塞中……\n",id);flag = 1;sleep(1);};
//将互斥变量置0,代表已占用
proCmutex--;
if(flag == 1)
printf("生产者%d生产唤醒!\n",id);
//产品号+1
proCount++;
printf("生产者%d:生产一个产品ID%d!\n",id,proCount);
//总互斥变量,检查有没有其他进程修改缓冲区数据
flag = 0;
while(mutex
int id = ++consumer_id;
while(true){
int flag = 0;
while(full printf("\t\t\t\t消费者%d消费阻塞中……\n",id);sleep(1);};
mutex--;
if(flag == 1)
printf("\t\t\t\t消费者%d消费唤醒!\n",id);
int nextc = buffer[out];
buffer[out] = 0;//消费完将缓冲区设置为0
empty++;
printf("\t\t\t\t消费者%d:消费一个产品ID%d,缓冲区位置为%d\n",id, nextc,out);
out = (out + 1) % N;
mutex++;
sleep(1);
}
}
int main()
{
int tempnum;
//输入生产者数目
printf("请输入生产者数目:\n");
scanf("%d",&tempnum);
producerNum = tempnum;
//输入消费者数目
printf("请输入消费者数目:\n");
scanf("%d",&tempnum);
consumerNum = tempnum;
//输入缓冲区大小
printf("请输入缓冲区大小:\n");
scanf("%d",&tempnum);
N = tempnum;
empty = N;
buffer = (item*)malloc(N*sizeof(item));
for(int i=0;i
pthread_t temp;
//if语句中,第一个参数是线程指针,第二个是线程属性指针,第三个是函数指针,即线程要执行的代码
//函数通过producer函数指针创建对象,赋值给temp作为线程执行
if(pthread_create(&temp, NULL, producer, NULL) == -1)
{
printf("ERROR, fail to create producer%d\n", i);
exit(1);
}
//将temp作为能够执行的线程放入了进程池
threadPool[i] = temp;
}//创建生产者进程放入线程池
//对于消费者进程也同样创建进程
for(i = 0; i
printf("ERROR, fail to create consumer%d\n", i);
exit(1);
}
threadPool[i+producerNum] = temp;
}//创建消费者进程放入线程池
void * result;
for(i = 0; i
printf("fail to recollect\n");
exit(1);
}
}//运行线程池
return 0;
}
3.编译运行结果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201117215835425.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNDE3MDAz,size_16,color_FFFFFF,t_70#pic_center)
|