生产者——消费者问题(producers and consumers,problem)
/*伪代码*/
#define BUFFER_SIZE k
itemType buffer[BUFFER_SIZE];//全局数组作为线程间共享的数据
int in=0;//in为放入指针
int out=0;//out为取出指针
int count=0;count为缓冲区已放入指针计数量
semaphore mutex=1;//静态创建锁或全局变量动态锁
pthread_cond_t p_cond=PTHREAD_COND_INITIALIZER;//条件变量初始化为PTHREAD_COND_INITIALIZER;
/*生产者伪代码*/
void producer(){
while(1){
produceItem(&item);
P(s1);
P(mutex);
buffer[in]=item;
in=(in+1)%BUFFER_SIZE;
V(mutex);
V(s2);
}
}
/*消费者伪代码*/
void consumer(){
itemType x;
while(1){
P(s2);
P(mutex);
x=buffer[out];
out=(out+1)%BUFFER_SIZE;
V(mutex);
V(s1);
consumeItem(x);
}
}
/*用pthread线程+condition variables+mutex模拟第3题的“生产者-消费者”问题*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>//信号量sem_t函数头文件
#include "buffer.h" //缓冲区头文件
buffer_item buffer[BUFFER_SIZE];//全局数组作为线程间共享的数据
int in_pthread=0,out_pthread=0;//in_pthread为放入指针,out_pthread为取出指针
int count_pthread=0;//counr_pthread为缓冲区已放入指针计数量
pthread_mutex_t p_lock;//全局变量动态锁
pthread_cond_t p_cond;//条件变量
void *producer(void *param);//生产者线程
void *consumer(void *param);//消费者线程
int insert_item(buffer_item item);//生产者插入
int remove_item(buffer_item *item);//消费者取出
int main(int argc,char *argv[])
{
/*判断参数的合法性*/
if(argc<4)
{
printf("lack of parameters\n");
exit(0);
}
int n=atoi(argv[1]);
if(n<0)
{
printf("Wrong input of sleep time!\n");
exit(0);
}
if(atoi(argv[2])<0)
{
printf("Wrong input of producer threads numbers!\n");
exit(0);
}
if(atoi(argv[3])<0)
{
printf("Wrong input of consumer threads numbers!\n");
exit(0);
}
/*创建锁及条件变量初值*/
pthread_mutex_init(&p_lock,NULL);//动态创建锁
pthread_cond_init(&p_cond,NULL);//条件变量初始化
/*创建生产者线程*/
int i;
for(i=1;i<=atoi(argv[2]);i++)
{
pthread_t tid_producer;
pthread_attr_t attr;//const pthread_attr_t *attr的分离属性
pthread_attr_init(&attr);
pthread_create(&tid_producer,&attr,producer,(void *)i);
}
/*创建消费者线程*/
for(i=1;i<=atoi(argv[3]);i++)
{
pthread_t tid_consumer;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tid_consumer,&attr,consumer,(void *)i);
}
pthread_mutex_destroy(&p_lock);//删除动态锁
/*sleep等待n秒*/
sleep(n);
return 0;
}
void *producer(void *param)
{
buffer_item item;
srand((unsigned)time(NULL));
while(1)
{
sleep(rand()%5+1);//睡1~5范围内的随机秒数
item=rand()%5+1;//生成1~5范围内的随机整数
if(insert_item(item))
printf("Produce error\n");//打印“出错信息”
else
printf("Producer thread %d produce %d\n",param,item);//打印“生产者线程param生产了item”
}
pthread_exit(0);
}
void *consumer(void *param)
{
buffer_item item;
srand((unsigned)time(NULL));
while(1)
{
sleep(rand()%5+1);//睡1~5范围内的随机秒数
if(remove_item(&item))
printf("Remove error\n");//打印“出错信息”
else
printf("Consumer thread %d consume %d\n",param,item);//打印“消费者线程param消费了item”
}
pthread_exit(0);
}
int insert_item(buffer_item item)//insert item into buffer
{
if(count_pthread==BUFFER_SIZE)
return -1;
else
{
pthread_mutex_lock(&p_lock);//上锁
while((in_pthread+1)%BUFFER_SIZE==out_pthread || count_pthread==BUFFER_SIZE)//缓冲区为满时等待
{
pthread_cond_wait(&p_cond,&p_lock);//等待缓冲区非空,wait的同时会原子释放锁
}
buffer[in_pthread]=item;
in_pthread=(in_pthread+1)%BUFFER_SIZE;
count_pthread++;
//printf("P---> %d\n",count_pthread);测试count_pthread的值
pthread_mutex_unlock(&p_lock);//解锁
}
return 0;
}
int remove_item(buffer_item *item)//remove item from buffer
{//使用*item是为了从buffer中取数
if(count_pthread==0)
return -1;
else
{
pthread_mutex_lock(&p_lock);//上锁
*item=buffer[out_pthread];
buffer[out_pthread]=0;
out_pthread=(out_pthread+1)%BUFFER_SIZE;
count_pthread--;
//printf("C<--- %d,item=%d\n",count_pthread,*item);//测试count_pthread的值
if(in_pthread==out_pthread)
pthread_cond_signal(&p_cond);//被唤醒,重新获得锁并返回
pthread_mutex_unlock(&p_lock);//解锁
}
return 0;
}
友情链接:
(1)生产者和消费者问题
https://wenku.baidu.com/view/e8a53ff32b160b4e777fcfbc.html
(2)互斥锁和条件变量实现生产者消费者问题
http://www.cnblogs.com/XNQC1314/p/9178120.html
(3)生产者消费者模型(Linux系统下的两种实现方法)
https://blog.csdn.net/yusiguyuan/article/details/48265205
(4)线程-条件变量(实现生产者和消费者问题)
https://blog.csdn.net/qq_38635597/article/details/80045817
(5)条件变量
https://www.cnblogs.com/ACGame/p/9102241.html
(6)深入解析条件变量(condition variables)
https://www.cnblogs.com/harlanc/p/8596211.html
意外发现:
(1)生产者消费者问题的pthread模拟
https://blog.csdn.net/sinat_16709955/article/details/75208019