Linux程式設計:程式同步問題之哲學家就餐問題
哲學家就餐問題描述
5個哲學家用一生的時間吃飯和思考。他們共用一張圓桌,每人都有一張椅子,桌上放著5支筷子。每個哲學家感到飢餓時,會試圖拿起左右的兩隻筷子,每位哲學家每次只能拿起一隻筷子。當每位哲學家同時有兩支筷子的時候,他可以吃飯。當他吃完後,他會放下筷子,並開始思考。
我們需要保證不會出現哲學家餓死的情況發生。
此博文采用以下兩種方法解決哲學家就餐問題:
- 要求每位哲學家同時拿起兩隻筷子。
- 要求座位號為奇數的哲學家先拿左手的筷子,偶數的哲學家先拿右手的筷子。
完整程式碼如下(僅供參考):
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<semaphore.h>
#define Phi_Number 5
pthread_mutex_t chopstick[5] ;
void *solve1(void *arg)
{
int phi = *(int *)arg;
int left,right;
switch (phi)
{
case 1:
left = 5;
right = 1;
break;
case 2:
left = 1;
right = 2;
break;
case 3:
left = 2;
right = 3;
break;
case 4:
left = 3;
right = 4;
break;
case 5:
left = 4;
right = 5;
break;
}
while(1)
{
printf("Philosopher %d is thiking !\n",phi);
sleep(1); // thinking
pthread_mutex_lock(&chopstick[left]); // Ruquest left chopstick
time_t timep11;
time (&timep11);
printf("Philosopher %d takes left chopstick %d at %s",phi,left,asctime(gmtime(&timep11)));
if (pthread_mutex_trylock(&chopstick[right]))//return 0 if success
{
pthread_mutex_unlock(&chopstick[left]); // Release left chopstick
printf("Philosopher %d release left chopstick %d\n", phi, left);
continue;
}
time_t timep1;
time (&timep1);
printf("Philosopher %d takes right chopstick %d at %s", phi, right,asctime(gmtime(&timep1)));
printf("!!!!!!!!!!!!!!!!!!!!!Philosopher %d is eating~<>_<>~.\n",phi);
sleep(3); // eating
pthread_mutex_unlock(&chopstick[left]); // Release left chopstick
printf("Philosopher %d release left chopstick %d\n", phi, left);
pthread_mutex_unlock(&chopstick[right]); // Release right chopstick
printf("Philosopher %d release right chopstick %d\n", phi, right);
pthread_exit(0);
}
}
void *solve2(void *arg)
{
int phi = *(int *)arg;
int left,right;
switch (phi)
{
case 1:
left = 5;
right = 1;
break;
case 2:
left = 1;
right = 2;
break;
case 3:
left = 2;
right = 3;
break;
case 4:
left = 3;
right = 4;
break;
case 5:
left = 4;
right = 5;
break;
}
while(1)
{
printf("Philosopher %d is thiking !\n",phi);
sleep(1); // thinking
if(phi%2 != 0)//Odd Number
{
pthread_mutex_lock(&chopstick[left]); // Ruquest left chopstick
time_t timep11;
time (&timep11);
printf("Philosopher %d takes left chopstick %d at %s",phi,left,asctime(gmtime(&timep11)));
if (pthread_mutex_trylock(&chopstick[right]))//return 0 if success
{
pthread_mutex_unlock(&chopstick[left]); // Release left chopstick
printf("Philosopher %d release left chopstick %d\n", phi, left);
continue;
}
time_t timep1;
time (&timep1);
printf("Philosopher %d takes right chopstick %d at %s\n",phi,right,asctime(gmtime(&timep11)));
printf("!!!!!!!!!!!!!!!!!!!!!Philosopher %d is eating~<>_<>~.\n",phi);
sleep(3); // eating
pthread_mutex_unlock(&chopstick[left]); // Release left chopstick
printf("Philosopher %d release left chopstick %d\n", phi, left);
pthread_mutex_unlock(&chopstick[right]); // Release right chopstick
printf("Philosopher %d release right chopstick %d\n", phi, right);
pthread_exit(0);
}
else{
pthread_mutex_lock(&chopstick[right]); // Ruquest left chopstick
time_t timep1;
time (&timep1);
printf("Philosopher %d takes right chopstick %d at %s",phi,right,asctime(gmtime(&timep1)));
if (pthread_mutex_trylock(&chopstick[left]))//return 0 if success
{
pthread_mutex_unlock(&chopstick[right]); // Release left chopstick
printf("Philosopher %d release right chopstick %d\n", phi, right);
continue;
}
time_t timep11;
time (&timep11);
printf("Philosopher %d takes left chopstick %d at %s\n",phi,left,asctime(gmtime(&timep11)));
printf("!!!!!!!!!!!!!!!!!!!!!Philosopher %d is eating~<>_<>~.\n",phi);
sleep(3); // eating
pthread_mutex_unlock(&chopstick[right]); // Release left chopstick
printf("Philosopher %d release right chopstick %d\n", phi, right);
pthread_mutex_unlock(&chopstick[left]); // Release right chopstick
printf("Philosopher %d release left chopstick %d\n", phi, left);
pthread_exit(0);
}
}
}
int main()
{
int choose;
printf("Enter 1 for solve1,2 for solve2:\n");
scanf("%d",&choose);
pthread_t Philos[Phi_Number];
int ret[Phi_Number];
int i,j,k,m;
for (i = 0; i < Phi_Number; i++){
pthread_mutex_init(&chopstick[i],NULL);
}
int a[5] = {1,2,3,4,5};
if(choose == 1)
{
ret[0] = pthread_create(&Philos[0],NULL,&solve1, &a[0]);
ret[1] = pthread_create(&Philos[1],NULL,&solve1, &a[1]);
ret[2] = pthread_create(&Philos[2],NULL,&solve1, &a[2]);
ret[3] = pthread_create(&Philos[3],NULL,&solve1, &a[3]);
ret[4] = pthread_create(&Philos[4],NULL,&solve1, &a[4]);
//sleep(1); //指執行緒被呼叫時,佔著CPU不工作,其他執行緒無法進入
}
if(choose == 2)
{
ret[0] = pthread_create(&Philos[0],NULL,&solve2, &a[0]);
ret[1] = pthread_create(&Philos[1],NULL,&solve2, &a[1]);
ret[2] = pthread_create(&Philos[2],NULL,&solve2, &a[2]);
ret[3] = pthread_create(&Philos[3],NULL,&solve2, &a[3]);
ret[4] = pthread_create(&Philos[4],NULL,&solve2, &a[4]);
//sleep(1); //指執行緒被呼叫時,佔著CPU不工作,其他執行緒無法進入
}
pthread_join(Philos[0],NULL);
pthread_join(Philos[1],NULL);
pthread_join(Philos[2],NULL);
pthread_join(Philos[3],NULL);
pthread_join(Philos[4],NULL);
return 0;
}
程式碼不足:裡面有許多重複使用的程式碼,沒有實現較好的程式碼複用
主要程式碼提要:
int pthread_mutex_lock(pthread_mutex_t *mutex)
//功能:對訊號量執行P操作
int pthread_mutex_unlock(pthread_mutex_t *mutex)
//功能:對訊號量執行V操作
執行結果截圖:
相關文章
- 哲學家就餐問題詳解
- 用c++設計哲學家進餐問題的求解C++
- java實現pv操作 -------哲學家問題Java
- 程式碼設計問題
- Linux_FAQ:程式設計問題(轉)Linux程式設計
- 無名訊號量實現哲學家問題
- 程式設計文化的問題程式設計
- Unix(Linux) C程式設計問題精粹 (轉)LinuxC程式程式設計
- Unix(Linux) C程式設計問題精粹(轉)LinuxC程式程式設計
- Unix(Linux)C程式設計問題精粹(轉)LinuxC程式程式設計
- 程式設計師”青春飯”問題之我見程式設計師
- 程式設計師"青春飯"問題之我見程式設計師
- 程式設計藝術家經典試題解讀:猜生日問題程式設計
- 程式設計師,你會問問題嗎?程式設計師
- PCL常見程式設計問題程式設計
- java的socket程式設計問題Java程式設計
- Linux TCP程式設計常見問題考慮LinuxTCP程式設計
- 關於詳細設計/程式碼的同步問題--請教
- 程式語言設計,程式設計哲學程式設計
- 程式導向程式設計哲學程式設計
- 圖形程式設計問題記錄程式設計
- 程式設計師需要自問的 10 個問題程式設計師
- JAVA程式設計題-用java解決兔子問題Java程式設計
- 程式設計師的哲學程式設計師
- 程式設計師面試常問計算機網路問題程式設計師面試計算機網路
- 程式設計師在程式設計中遇到的奇葩弱智問題程式設計師
- socket程式設計中常見的概念問題!程式設計
- Java程式設計師面試常見問題Java程式設計師面試
- Java程式設計常見問題彙總Java程式設計
- 【MyBatis】1:JDBC程式設計存在的問題MyBatisJDBCC程式程式設計
- 最令程式設計師生厭的問題程式設計師
- 池建強:程式設計師,你會問問題嗎?程式設計師
- Java訊號量實現程式同步問題:水果蘋果香蕉問題Java蘋果
- 好程式設計師分享:Java面試題常見問題程式設計師Java面試題
- 提出問題,解答問題!這才是理解程式碼設計的正確方法
- 漫談哲學與程式設計程式設計
- linux fork程式空間問題Linux
- 程式設計之美:螞蟻爬杆問題的擴充套件程式設計套件