linux 條件變數 互斥鎖的實現
阿新 • • 發佈:2018-12-25
這是一個經典的猴子吃桃子的問題的實現(生產-消費者問題)
有一棵桃樹和一隻猴子,開始的時候桃樹上沒有桃子,然後開始一個一個的長,每長一個猴子就吃一個,猴子吃了之後再長一個,又被猴子吃掉,猴子需要吃7個桃子,才能吃飽。編寫程式模擬這個猴子吃桃子的過程。
一看這肯定是兩個執行緒,一個是桃樹長桃子,一個是猴子吃桃子,歸根是一個生產者和消費者的問題。
注意事項
互斥鎖用起來比較簡單,條件變數會有點東西
條件變數其實就是一種通知,等待機制,要學會用這種機制去解決問題,語法也是相當之簡單的,看下面這個程式碼就可以了
注意的是pthread_cond_wait 這個裡面,可以理解是把鎖借出去了的感覺~
程式碼
#include <stdio.h>
#include <pthread.h>
#define COUNT 7 // 一共需要吃多少桃子
static int int_grow_number = 0; // 已經長了多少桃子
static int int_eat_number = 0; // 已經吃了多少桃子
pthread_mutex_t lock;
pthread_cond_t can_eat;// 猴子可以吃桃子了。
pthread_cond_t can_grow; // 桃樹需要長桃子
void *eat(void *data)
{
int n;
while(1)
{
pthread_mutex_lock(&lock);
if(int_grow_number == int_eat_number){
pthread_cond_wait(&can_eat, &lock); // 已經吃完所有的桃子
}
if(int_grow_number == -1){
printf("本猴子已經吃飽\n");
}else{
int_eat_number ++;
printf("猴子正吃第 (%d) 個桃子\n" ,int_eat_number);
}
sleep(1);
pthread_cond_signal(&can_grow); //通知桃樹長桃子
pthread_mutex_unlock(&lock);
if(int_grow_number == -1)
break;
};
return NULL;
}
void *grow(void *data)
{
while (1)
{
pthread_mutex_lock(&lock);
if(int_grow_number >= int_eat_number+1){
pthread_cond_wait(&can_grow, &lock); // 等待猴子吃桃子
}
if(int_grow_number >= COUNT){ // 檢查猴子是否吃飽了
int_grow_number = -1; // 沒得吃了
printf("本次餵食結束 \n");
}else{
int_grow_number ++;
printf("桃樹正長第 (%d) 個桃子 \n",int_grow_number);
}
pthread_cond_signal(&can_eat); // 通知猴子可以吃桃子
pthread_mutex_unlock(&lock);
if (int_grow_number == -1)
break;
}
return NULL;
}
int main(void)
{
pthread_t th_peach, th_monkey;
void *retval;
pthread_mutex_init(&lock, NULL);
pthread_cond_init(&can_eat, NULL);
pthread_cond_init(&can_grow, NULL);
pthread_create(&th_peach, NULL, grow, 0);
pthread_create(&th_monkey, NULL,eat, 0);
/* 等待猴子吃飽,結束*/
pthread_join(th_peach, &retval);
pthread_join(th_monkey, &retval);
pthread_mutex_destroy(&lock);
pthread_cond_destroy(&can_eat);
pthread_cond_destroy(&can_grow);
return 0;
}