问题描述:缓冲区大小为N,生产者产生物品放到缓冲区,消费者将物品从缓冲区移走
互斥关系:对缓冲区得访问需要互斥,包括生产者和生产者之间、消费者和消费者之间、生产者和消费者之间。
同步关系:当缓冲区满时生产者进程需要等待,当缓冲区空时消费者进程需要等待。
解题思路:用信号量解决生产者消费者问题。
互斥:有界缓冲区是一个临界资源,对临界资源得访问需要设置一个信号量mutex
同步:
设置两个同步信号量empty和full,其初值分别为n、0,用于临界资源得具体数目,同时也可以表示等待条件
C语言代码实现如下:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include<semaphore.h>
extern int pthread_setconcurrency();
#define N 5
sem_t empty, full; //定义全局同步信号量empty,full
pthread_mutex_t mutex; //定义一个全局互斥量,在不同函数中
int buffer_count = 0; //定义一个全局变量,表示管道内得产品数目
void *producer(void *arg); //生产者线程
void *consumer(void *arg); //消费者线程
int main(int argc, char *argv[]) {
pthread_t thrd_prod, thrd_cons;
pthread_mutex_init(&mutex, NULL); //初始化互斥量
sem_init(&empty, 0, N); //初始化empty信号量
sem_init(&full, 0, 0); //初始化full信号量
pthread_setconcurrency(2);
//创建生产者和消费者线程
if (pthread_create(&thrd_prod, NULL, producer,
NULL) != 0)
printf("thread create failed.");
if (pthread_create(&thrd_cons, NULL, consumer,
NULL) != 0)
printf("thread create failed.");
//等待线程结束
if (pthread_join(thrd_prod, NULL) != 0)
printf(" wait thread failed.");
if (pthread_join(thrd_cons, NULL) != 0)
printf(" wait thread failed.");
sem_destroy(&full); //释放同步量
sem_destroy(&empty); //释放同步量
pthread_mutex_destroy(&mutex); //关闭互斥量
return 0;
}
void *producer(void *arg) {
while (1) {
sem_wait(&empty); //empty-1
pthread_mutex_lock(&mutex); //加锁
//成功占有互斥量,接下来可以对缓冲区(仓库)进行生产
//操作
printf(" producer put a product to buffer.");
buffer_count++;
printf("the buffer_count is %d\n", buffer_count);
pthread_mutex_unlock(&mutex); //解锁
sem_post(&full); //full+1
sleep(1);
}
}
void *consumer(void *arg) {
while (1)
{
sem_wait(&full); //full-1
pthread_mutex_lock(&mutex); //加锁
//成功占有互斥量,接下来可以对缓冲区(仓库)进行取出
//操作
printf(" consumer get a product from buffer.");
buffer_count--;
printf("the buffer_count is %d\n", buffer_count);
pthread_mutex_unlock(&mutex); //解锁
sem_post(&empty); //empty-1
sleep(3);
}
}
结果如下: