- 生產者消費者問題
這是一個非常經典的多線程題目,題目大意如下:有一個生產者在生產產品,這些產品將提供給若干個消費者去消費,爲了使生產者和消費者能併發執行,在兩者之間設置一個有多個緩衝區的緩衝池,生產者將它生產的產品放入一個緩衝區中,消費者可以從緩衝區中取走產品進行消費,所有生產者和消費者都是異步方式運行的,但它們必須保持同步,即不允許消費者到一個空的緩衝區中取產品,也不允許生產者向一個已經裝滿產品且尚未被取走的緩衝區中投放產品。
#include <stdlib.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <semaphore.h>
sem_t sem_product; // 產品信號量
sem_t sem_space; // 倉庫容量信號量
typedef struct{
int space;
int product;
}pd_sp_def;
pd_sp_def pd_sp;
void* pth_consume(void* arg)
{
char* name = (char*)arg;
int cnt;
while (1)
{
//對產品個數減一
sem_wait(&sem_product);
pd_sp.product--;
pd_sp.space++;
printf("consume %s space:%d, product=%d\n",name,pd_sp.space, pd_sp.product);
//相應的空間加一
sem_post(&sem_space);
sem_getvalue(&sem_product, &cnt);
//printf("Csm Thread %s consume, count:%d\n", name, , cnt);
sleep(2); // 每隔2S消費一個產品
}
pthread_exit(0);
}
void* pth_product(void* arg)
{
char* name = (char*)arg;
int cnt;
while (1)
{
//剛開始空間是5,空間減一
sem_wait(&sem_space);
pd_sp.product++;
pd_sp.space--;
printf("product %s space:%d, product=%d\n",name,pd_sp.space, pd_sp.product);
//產品生產加一
sem_post(&sem_product);
sem_getvalue(&sem_product, &cnt);
//printf("pro Thread %s product, count:%d\n", name, cnt);
sleep(1); // 每隔1S生產一個產品
}
pthread_exit(0);
}
int main()
{
pthread_t tid1, tid2, tid3, tid4;
int ret;
pd_sp.space = 5;
pd_sp.product = 0;
// 初始化信號量
sem_init(&sem_product, 0, 0); // 初始狀態產品個數爲0
sem_init(&sem_space, 0, 5); // 初始狀態倉庫空間爲5
ret = pthread_create(&tid1, NULL, pth_product, "A");
if (0 != ret)
{
perror("create pthead error");
return -1;
}
ret = pthread_create(&tid2, NULL, pth_product, "B");
if (0 != ret)
{
perror("create pthead error");
return -1;
}
ret = pthread_create(&tid3, NULL, pth_consume, "C");
if (0 != ret)
{
perror("create pthead error");
return -1;
}
ret = pthread_create(&tid4, NULL, pth_consume, "D");
if (0 != ret)
{
perror("create pthead error");
return -1;
}
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_join(tid3, NULL);
pthread_join(tid4, NULL);
// 銷燬信號量
sem_destroy(&sem_product);
sem_destroy(&sem_space);
return 0;
}
product B space:4, product=1
consume D space:5, product=0
product A space:4, product=1
consume C space:5, product=0
product B space:4, product=1
product A space:3, product=2
product B space:2, product=3
consume D space:3, product=2
consume C space:4, product=1
product A space:3, product=2
product B space:2, product=3
product A space:1, product=4
consume D space:2, product=3
product B space:1, product=4
consume C space:2, product=3
product A space:1, product=4
product B space:0, product=5
consume D space:1, product=4
product A space:0, product=5
consume C space:1, product=4
product B space:0, product=5