Linux下生产者消费者问题
题目:
- 5个生产者
- 4个消费者
- 3缓冲区
- 总共15个产品,这15个产品被消耗以后生产者消费者线程都结束
要求
- 每个产品的数据结构:至少包含产品编号、生产者编号、生产时间、缓冲区中存储编号、消费者编号;
- 生产和消费都需要随机时间(1~5s);
- 不能产生竞态、不能死锁
- 对公共缓冲区的操作:操作前、操作后要显示公共缓冲区中各个产品项的状态
解题思路
1.使用信号量对缓冲区里的数据进行同步;
(1)声明信号量
sem_t room_sem; //缓冲区现存空闲空间
sem_t product_sem; //缓冲区现在所有产品数量
(2)初始化信号量
int ret = sem_init(&room_sem, 0, POOL_SIZE-1);
ret = sem_init(&product_sem, 0, 0);
(3)关于信号量的使用可以参照博客
2.使用互斥量对临界区代码进行保护;
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);
3.使用结构体存储产品信息;
struct Product{
int p_id;
long pcer_id;
struct tm *p_time; //时间
int cache_number;
long c_id;
};
4.使用rand函数产生随机时间;
int x = rand()%5 //随机得到数0,1,2,3,4
下面是完整代码
#include<stdio.h>
#include<time.h>
#include<pthread.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<semaphore.h>
#define P_NUMBER 5 //the number of producer
#define C_NUMBER 4 //the number of consumer
#define POOL_SIZE 3 //the number of cache
int c_p = 0; //consume product
int p_p = 0; //produce product
sem_t room_sem; // synchronizing signal ,being used to reflect that there remains available room
sem_t product_sem; //synchronizing signal, being used to reflect that there exisits capable product
pthread_mutex_t mutex; //mutually exclusive lock
int count = 0;
struct tm *gettime(){ //acquire current time
time_t ptime;
struct tm *p;
time(&ptime);
p = gmtime(&ptime);
return p;
}
struct Product{
int p_id;
long pcer_id;
struct tm *p_time;
int cache_number;
long c_id;
} producer [POOL_SIZE];//the message of products
void *producer_fun(void *args){
printf("this is producer %ld thread\n",(long) args);
while (1)
{
usleep((rand()%5+1)*1000);
sem_wait(&room_sem);
pthread_mutex_lock(&mutex);
//producer starts to produce product
if(count == 15){
exit(1);
}
printf("*******************************There is no pre-operation state***************************************************\n");
printf(" product_id producer_id product_time POOL_id consumer_id\n");
for(int i = 0; i < 3;i++){
printf("%d %d %ld %d:%d:%d %d %ld\n",
i,
producer[i].p_id,
producer[i].pcer_id,
producer[i].p_time->tm_hour, producer[i].p_time->tm_min,producer[i].p_time->tm_sec,
producer[i].cache_number,
producer[i].c_id);
}
printf("*****************************************************************************************************************\n");
producer[p_p].cache_number = p_p;
producer[p_p].c_id = -1;
producer[p_p].p_id = count;
producer[p_p].p_time = gettime();
producer[p_p].pcer_id = (long)args;
count++;
printf("product %d is produced by producer %ld\n", producer[p_p].p_id, producer[p_p].pcer_id);
printf("*******************************There is the state after the operation********************************************\n");
printf(" product_id producer_id product_time POOL_id consumer_id\n");
for(int i = 0; i < 3;i++){
printf("%d %d %ld %d:%d:%d %d %ld\n",
i,
producer[i].p_id,
producer[i].pcer_id,
producer[i].p_time->tm_hour, producer[i].p_time->tm_min,producer[i].p_time->tm_sec,
producer[i].cache_number,
producer[i].c_id);
}
printf("****************************************************************************************************************\n\n\n");
p_p = (p_p + 1)%POOL_SIZE;
pthread_mutex_unlock(&mutex);
sem_post(&product_sem);
}
}
void *consumer_fun(void *args){
printf("this is consumer %ld thread\n", (long) args);
while(1){
usleep((rand()%5+1)*1000);
sem_wait(&product_sem);
pthread_mutex_lock(&mutex);
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~There is no pre-operation state~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
printf(" product_id producer_id product_time POOL_id consumer_id\n");
for(int i = 0; i < 3;i++){
printf("%d %d %ld %d:%d:%d %d %ld\n",
i,
producer[i].p_id,
producer[i].pcer_id,
producer[i].p_time->tm_hour, producer[i].p_time->tm_min,producer[i].p_time->tm_sec,
producer[i].cache_number,
producer[i].c_id);
}
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
producer[c_p].c_id = (long)args;
printf("product %d was customed by customer %ld\n", producer[c_p].p_id, producer[c_p].c_id);
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~There is the state after the operation~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
printf(" product_id producer_id product_time POOL_id consumer_id\n");
for(int i = 0; i < 3;i++){
printf("%d %d %ld %d:%d:%d %d %ld\n",
i,
producer[i].p_id,
producer[i].pcer_id,
producer[i].p_time->tm_hour, producer[i].p_time->tm_min,producer[i].p_time->tm_sec,
producer[i].cache_number,
producer[i].c_id);
}
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n\n");
c_p = (c_p + 1)%POOL_SIZE;
pthread_mutex_unlock(&mutex);
sem_post(&room_sem);
}
}
int main()
{
pthread_t producer_id[P_NUMBER];
pthread_t consumer_id[C_NUMBER];
pthread_mutex_init(&mutex, NULL);
for(int i=0; i<POOL_SIZE;i++){
producer[i].pcer_id = -1;
producer[i].p_id = -1;
producer[i].cache_number = -1;
producer[i].c_id = -1;
producer[i].p_time = gettime();
}
int ret = sem_init(&room_sem, 0, POOL_SIZE-1);
if(ret != 0){
printf("sem_int error \n");
exit(1);
}
ret = sem_init(&product_sem, 0, 0);
if(ret != 0){
printf("sem_int error!\n");
exit(1);
}
for(long i = 0; i<P_NUMBER;i++){
ret = pthread_create(&producer_id[i], NULL, producer_fun, (void*)i);
if(ret != 0){
printf("creating producer_id errors!\n ");
exit(1);
}
}
for(long i = 0; i<C_NUMBER; i++){
ret = pthread_create(&consumer_id[i], NULL, consumer_fun, (void*)i);
if(ret != 0){
printf("creating consumer errors!\n");
exit(1);
}
}
for(int i=0;i<C_NUMBER;i++){
pthread_join(producer_id[i], NULL);
pthread_join(consumer_id[i], NULL);
}
pthread_join(producer_id[4], NULL);
return 0;
}
下面是结果
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)