生產者消費者的c語言版本實現
//程式碼可直接編譯通過
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#define MAX_STOCK 20//容量
char g_storage[MAX_STOCK];
size_t g_stock = 0;//當前庫存
pthread_mutex_t g_mtx = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t g_full = PTHREAD_COND_INITIALIZER;
pthread_cond_t g_empty = PTHREAD_COND_INITIALIZER;
void show(const char* who,const char* op,char prod){
printf("%s:",who);
size_t i;
for(i < 0;i < g_stock;++i)
printf("%c",g_storage[i]);
printf("%s%c\n",op,prod);
}
void* producer(void* arg)
{
const char* who = (const char*)arg;
for(;;){
pthread_mutex_lock(&g_mtx);
while(g_stock >= MAX_STOCK){//此處必須用while判斷,防止條件失效。試想兩個producer都阻塞在
//wait上,之後一個被喚醒。生產之後,另一個又返回去生產,導致越界。
printf("%s:full\n",who);
pthread_cond_wait(&g_full,&g_mtx);
//此函式阻塞,同時Mutex會解鎖,返回之前需重新獲取這把鎖
}
char prod = 'A' + rand()%26;
show(who,"<-",prod);
g_storage[g_stock++] = prod;
pthread_cond_broadcast(&g_empty);
pthread_mutex_unlock(&g_mtx);
usleep((rand()%100)*1000);
}
return NULL;
}
void* customer(void* arg){
const char* who = (const char*)arg;
for(;;){
pthread_mutex_lock(&g_mtx);
while(!g_stock){
printf("%s:空倉\n",who);
pthread_cond_wait(&g_empty,&g_mtx);
//g_empty初始化之後無訊號,之後進入阻塞.
}
char prod = g_storage[--g_stock];
show(who,"->",prod);
pthread_cond_broadcast(&g_full);//只有有執行緒阻塞的時候發訊號才有效.
pthread_mutex_unlock(&g_mtx);
usleep((rand()%100)*1000);
}
return NULL;
}
int main(void){
srand(time(NULL));
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
pthread_t tid;
pthread_create(&tid,&attr,producer,"prodecer1");
pthread_create(&tid,&attr,producer,"prodecer2");
pthread_create(&tid,&attr,customer,"customer1");
pthread_create(&tid,&attr,customer,"customer2");
getchar();
}
//pthread_cond_broadcast(&g_full)叫醒所有的,pthread_cond_signal(&g_full)只喚醒一個