生产者-消费者问题是一个著名的进程同步问题。它描述的为:有一群生产者进程在生产产品,并将这些产品提供给消费者进程消费。为使生产者进程与消费者进程能并发执行,在两者之间设置一个具有n个缓存区的缓冲池,生产者进程将其所生产的产品放入一个缓冲区;消费者进程可从一个缓冲区中取走产品去消费。尽管所有生产者和消费者进程都是异步方式运行的,但它们之间必须保持同步,既不允许消费者进程到一个空缓冲区取产品,也不允许生产者进程向一个已装满产品且尚未被取走的缓冲区中投放产品。
<1> 单生产者和单消费者
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
sem_t space_sem,data_sem;//信号量
int buf[10];//缓冲区
void* sem_producter(void* arg) //生产者
{
int start = 0;
while(1)
{
sem_wait(&space_sem); //P操作 申请空间,若空间为0,挂起
int data = rand()%1234;
printf("producter data : %d\n",data);
buf[start] = data;
start++;
start %= 10;
sem_post(&data_sem);//V操作 申请数据,若数据为0,挂起
sleep(1);
}
}
void* sem_consumer(void* arg) //消费者
{
int start = 0;
while(1)
{
sem_wait(&data_sem);
int data = buf[start];
printf("consumer data : %d\n",data);
start++;
start %= 10;
sem_post(&space_sem);
//sleep(1);
}
}
int main()
{
sem_init(&space_sem,0,10);//初始化信号量
sem_init(&data_sem,0,0);
pthread_t id1,id2,id3,id4;
pthread_create(&id1,NULL,sem_producter,NULL); //创建线程
pthread_create(&id2,NULL,sem_consumer,NULL);
pthread_join(id1,NULL);//等待进程
pthread_join(id2,NULL);
sem_destroy(&space_sem);//释放资源
sem_destroy(&data_sem);
return 0;
}
若生产者sleep(1),生产一个消费一个。当缓冲区为空时,消费者挂起,直到生产者生产产品才会唤醒消费者去消费。
若消费者sleep(1),则生产者会先将缓冲区生产满,然后挂起,直到消费者消费一个,才能唤醒生产者生产产品。
<2> 多生产者多消费者(以两个生产者两个消费者为例)
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
sem_t space_sem,data_sem; //信号量
int buf[10];//缓冲区
static start = 0;
static begin = 0;
void* sem_producter(void* arg)
{
while(1)
{
sem_wait(&space_sem); //申请空间 P操作
int data = rand()%1234;
printf("producter data : %d\n",data);
buf[start] = data;
start++;
start %= 10;
sem_post(&data_sem); //释放数据 V操作
sleep(1);
}
}
void* sem_consumer(void* arg)
{
while(1)
{
sem_wait(&data_sem); //申请数据 P操作
int data = buf[begin];
printf("consumer data : %d\n",data);
begin++;
begin %= 10;
sem_post(&space_sem); //释放空间 V操作
// sleep(1);
}
}
int main()
{
sem_init(&space_sem,0,10); //初始化,可用空间为10
sem_init(&data_sem,0,0);
pthread_t id1,id2,id3,id4;
pthread_create(&id1,NULL,sem_producter,NULL);
pthread_create(&id2,NULL,sem_consumer,NULL);
pthread_create(&id3,NULL,sem_producter,NULL);
pthread_create(&id4,NULL,sem_consumer,NULL);
pthread_join(id1,NULL);
pthread_join(id2,NULL);
pthread_join(id3,NULL);
pthread_join(id4,NULL);
sem_destroy(&space_sem);
sem_destroy(&data_sem);
return 0;
}
测试结果:
转载于:https://blog.51cto.com/10810429/1832527