問題描述:
五個哲學家共用一張圓桌,分別坐在周圍的五張椅子上,在桌子上有五隻碗和五隻筷子,他們的生活方式是交替地進行思考和進餐。平時,一個哲學家進行思考,飢餓時便試圖取用其左右最靠近他的筷子,只有在他拿到兩隻筷子時才能進餐。進餐畢,放下筷子繼續思考。
哲學家就餐問題是一個經典的同步問題,這不是因爲其本身的實際重要性,也不是因爲計算機科學家不喜歡哲學家,而是因爲它是大量併發控制問題的一個例子。這個代表型的例子滿足:在多個進程之間分配多個資源,而且不會出現死鎖和飢餓。
問題解法
至多隻允許四個哲學家同時進餐,以保證至少有一個哲學家能夠進餐,最終總會釋放出他所使用過的兩支筷子,從而可使更多的哲學家進餐。定義信號量num,只允許4個哲學家同時進餐,這樣就能保證至少有一個哲學家可以就餐。
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
pthread_mutex_t mutex,mutex1,mutex2,mutex3,mutex4,mutex5;
pthread_cond_t cond;
int num=4;
void* th1(void *a)
{
while(1){
if(num<1){
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond,&mutex);
pthread_mutex_unlock(&mutex);
}
pthread_mutex_lock(&mutex1);
num--;
printf("1號拿到左邊的筷子1\n");
pthread_mutex_lock(&mutex5);
printf("1號拿到右邊的筷子5\n1號開始喫飯\n");
sleep(1);
printf("1號喫完放下筷子\n");
pthread_mutex_unlock(&mutex1);
pthread_mutex_unlock(&mutex5);
num++;
pthread_cond_signal(&cond);
pthread_exit(NULL);
}
}
void* th2(void *a)
{
while(1){
if(num<1){
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond,&mutex);
pthread_mutex_unlock(&mutex);
}
pthread_mutex_lock(&mutex2);
num--;
printf("2號拿到左邊的筷子2\n");
pthread_mutex_lock(&mutex1);
printf("2號拿到右邊的筷子1\n2號開始喫飯\n");
sleep(1);
printf("2號喫完放下筷子\n");
pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex1);
num++;
pthread_cond_signal(&cond);
pthread_exit(NULL);
}
}
void* th3(void *a)
{
while(1){
if(num<1){
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond,&mutex);
pthread_mutex_unlock(&mutex);
}
pthread_mutex_lock(&mutex3);
num--;
printf("3號拿到左邊的筷子3\n");
pthread_mutex_lock(&mutex2);
printf("3號拿到右邊的筷子2\n3號開始喫飯\n");
sleep(1);
printf("3號喫完放下筷子\n");
pthread_mutex_unlock(&mutex3);
pthread_mutex_unlock(&mutex2);
num++;
pthread_cond_signal(&cond);
pthread_exit(NULL);
}
}
void* th4(void *a)
{
while(1){
if(num<1){
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond,&mutex);
pthread_mutex_unlock(&mutex);
}
pthread_mutex_lock(&mutex4);
num--;
printf("4號拿到左邊的筷子4\n");
pthread_mutex_lock(&mutex3);
printf("4號拿到右邊的筷子3\n4號開始喫飯\n");
sleep(1);
printf("4號喫完放下筷子\n");
pthread_mutex_unlock(&mutex4);
pthread_mutex_unlock(&mutex3);
num++;
pthread_cond_signal(&cond);
pthread_exit(NULL);
}
}
void* th5(void *a)
{
while(1){
if(num<1){
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond,&mutex);
pthread_mutex_unlock(&mutex);
}
pthread_mutex_lock(&mutex5);
num--;
printf("5號拿到左邊的筷子5\n");
pthread_mutex_lock(&mutex4);
printf("5號拿到右邊的筷子4\n5號開始喫飯\n");
sleep(1);
printf("5號喫完放下筷子\n");
pthread_mutex_unlock(&mutex5);
pthread_mutex_unlock(&mutex4);
num++;
pthread_cond_signal(&cond);
pthread_exit(NULL);
}
}
int main()
{
pthread_cond_init(&cond,NULL);
pthread_mutex_init(&mutex,NULL);
pthread_mutex_init(&mutex1,NULL);
pthread_mutex_init(&mutex2,NULL);
pthread_mutex_init(&mutex3,NULL);
pthread_mutex_init(&mutex4,NULL);
pthread_mutex_init(&mutex5,NULL);
pthread_t thid[5];
pthread_create(&thid[0],NULL,th1,NULL);
pthread_create(&thid[1],NULL,th2,NULL);
pthread_create(&thid[2],NULL,th3,NULL);
pthread_create(&thid[3],NULL,th4,NULL);
pthread_create(&thid[4],NULL,th5,NULL);
pthread_join(thid[0],NULL);
pthread_join(thid[1],NULL);
pthread_join(thid[2],NULL);
pthread_join(thid[3],NULL);
pthread_join(thid[4],NULL);
pthread_cond_destroy(&cond);
exit(0);
}