西方哲学史思维导图+脉络图_C和C ++中的餐饮哲学家问题

西方哲学史思维导图+脉络图

In this tutorial you will learn about Dining Philosophers Problem in C and C++ with program example.

在本教程中,您将通过程序示例了解C和C ++中的Dining Philosophers问题。

What is Dining Philosophers Problem?

饮食哲学家的问题是什么?

There are some Philosophers whose work is just thinking and eating. Let there are 5 (for example) philosophers. They sat at a round table for dinner. To complete dinner each must need two Forks (spoons). But there are only 5 Forks available (Forks always equal to no. of Philosophers) on table. They take in such a manner that, first take left Fork and next right Fork. But problem is they try to take at same time. Since they are trying at same time, Fork 1, 2, 3, 4, 5 taken by Philosopher 1, 2, 3, 4, 5 respectively (since they are left side of each). And each one tries to ta ke right side Fork. But no one found available Fork. And also that each one thinks that someone will release the Fork and then I can eat. This continuous waiting leads to Dead Lock situation.

有些哲学家的工作只是思考和饮食。 假设有5位(例如)哲学家。 他们坐在圆桌旁吃晚饭。 要完成晚餐,每个人都需要两个叉子(勺子)。 但是桌上只有5个货叉(货叉总是等于哲学家的人数)。 他们采取的方式是,先拿左叉,再拿右叉。 但是问题是他们试图同时服用。 由于他们同时尝试,因此哲学家1、2、3、4、5分别拿走了叉子1、2、3、4、5(因为它们分别在左边)。 并且每个人都试图拿右边的叉子。 但是没有人找到可用的叉子。 而且每个人都认为有人会放开叉子,然后我才能吃饭。 这种持续的等待导致死锁情况。

西方哲学史思维导图+脉络图_C和C ++中的餐饮哲学家问题

Also Read: Banker’s Algorithm in C

另请参阅: C语言中的银行家算法

Dining Arrangement

用餐安排

Solution: To solve this Dead Lock situation, Last philosopher (any one can do this) first try to take right side fork and then left side fork. i.e in our example 5th person tries to take 4th Fork instead of 5th one. Since 4th Fork already taken by 4th the person, he gets nothing. But he left 5th Fork. Now the first person will take this 5th Fork and complete dinner and make 1st and 5th available for remaining people. Next 2nd person takes 1st fork and completes and releases 1st and 2nd. This continuous until all finishes dinner.

解决方案:要解决这种“死锁”情况,最后一位哲学家(任何人都可以这样做)首先尝试拿起右侧的叉子,然后取左侧的叉子。 例如,在我们的示例中,第五个人尝试拿第四叉而不是第五叉。 由于第四叉已经被第四个人占用,他什么也得不到。 但是他离开了第五叉。 现在,第一个人将带上这把第五把叉子并完成晚餐,并为剩下的人提供第一把和第五把。 接下来的第二个人拿起第一把叉子,完成并放出第一把和第二把。 这一直持续到所有晚餐都吃完为止。

Operating System

操作系统

In Operating System, this concept used in process synchronization. Same problem but instead of Philosophers processes are there and instead of Forks Resources are there. We follow above solution to avoid dead lock condition.

在操作系统中,此概念用于进程同步。 同样的问题,而不是哲学家的过程,而不是Forks资源。 我们遵循上述解决方案以避免死锁情况。

C语言中的餐饮哲学家问题程序 (Program for Dining Philosophers Problem in C)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include<stdio.h>
#define n 4
int compltedPhilo = 0,i;
struct fork{
int taken;
}ForkAvil[n];
struct philosp{
int left;
int right;
}Philostatus[n];
void goForDinner(int philID){ //same like threads concept here cases implemented
if(Philostatus[philID].left==10 && Philostatus[philID].right==10)
        printf("Philosopher %d completed his dinner\n",philID+1);
//if already completed dinner
else if(Philostatus[philID].left==1 && Philostatus[philID].right==1){
            //if just taken two forks
            printf("Philosopher %d completed his dinner\n",philID+1);
            Philostatus[philID].left = Philostatus[philID].right = 10; //remembering that he completed dinner by assigning value 10
            int otherFork = philID-1;
            if(otherFork== -1)
                otherFork=(n-1);
            ForkAvil[philID].taken = ForkAvil[otherFork].taken = 0; //releasing forks
            printf("Philosopher %d released fork %d and fork %d\n",philID+1,philID+1,otherFork+1);
            compltedPhilo++;
        }
        else if(Philostatus[philID].left==1 && Philostatus[philID].right==0){ //left already taken, trying for right fork
                if(philID==(n-1)){
                    if(ForkAvil[philID].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION
                        ForkAvil[philID].taken = Philostatus[philID].right = 1;
                        printf("Fork %d taken by philosopher %d\n",philID+1,philID+1);
                    }else{
                        printf("Philosopher %d is waiting for fork %d\n",philID+1,philID+1);
                    }
                }else{ //except last philosopher case
                    int dupphilID = philID;
                    philID-=1;
                    if(philID== -1)
                        philID=(n-1);
                    if(ForkAvil[philID].taken == 0){
                        ForkAvil[philID].taken = Philostatus[dupphilID].right = 1;
                        printf("Fork %d taken by Philosopher %d\n",philID+1,dupphilID+1);
                    }else{
                        printf("Philosopher %d is waiting for Fork %d\n",dupphilID+1,philID+1);
                    }
                }
            }
            else if(Philostatus[philID].left==0){ //nothing taken yet
                    if(philID==(n-1)){
                        if(ForkAvil[philID-1].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION
                            ForkAvil[philID-1].taken = Philostatus[philID].left = 1;
                            printf("Fork %d taken by philosopher %d\n",philID,philID+1);
                        }else{
                            printf("Philosopher %d is waiting for fork %d\n",philID+1,philID);
                        }
                    }else{ //except last philosopher case
                        if(ForkAvil[philID].taken == 0){
                            ForkAvil[philID].taken = Philostatus[philID].left = 1;
                            printf("Fork %d taken by Philosopher %d\n",philID+1,philID+1);
                        }else{
                            printf("Philosopher %d is waiting for Fork %d\n",philID+1,philID+1);
                        }
                    }
        }else{}
}
int main(){
for(i=0;i<n;i++)
        ForkAvil[i].taken=Philostatus[i].left=Philostatus[i].right=0;
while(compltedPhilo<n){
/* Observe here carefully, while loop will run until all philosophers complete dinner
Actually problem of deadlock occur only thy try to take at same time
This for loop will say that they are trying at same time. And remaining status will print by go for dinner function
*/
for(i=0;i<n;i++)
            goForDinner(i);
printf("\nTill now num of philosophers completed dinner are %d\n\n",compltedPhilo);
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include<stdio.h>
#define n 4
int compltedPhilo = 0 , i ;
struct fork {
int taken ;
} ForkAvil [ n ] ;
struct philosp {
int left ;
int right ;
} Philostatus [ n ] ;
void goForDinner ( int philID ) { //same like threads concept here cases implemented
if ( Philostatus [ philID ] . left == 10 && Philostatus [ philID ] . right == 10 )
         printf ( "Philosopher %d completed his dinner\n" , philID + 1 ) ;
//if already completed dinner
else if ( Philostatus [ philID ] . left == 1 && Philostatus [ philID ] . right == 1 ) {
             //if just taken two forks
             printf ( "Philosopher %d completed his dinner\n" , philID + 1 ) ;
             Philostatus [ philID ] . left = Philostatus [ philID ] . right = 10 ; //remembering that he completed dinner by assigning value 10
             int otherFork = philID - 1 ;
             if ( otherFork == - 1 )
                 otherFork = ( n - 1 ) ;
             ForkAvil [ philID ] . taken = ForkAvil [ otherFork ] . taken = 0 ; //releasing forks
             printf ( "Philosopher %d released fork %d and fork %d\n" , philID + 1 , philID + 1 , otherFork + 1 ) ;
             compltedPhilo ++ ;
         }
         else if ( Philostatus [ philID ] . left == 1 && Philostatus [ philID ] . right == 0 ) { //left already taken, trying for right fork
                 if ( philID == ( n - 1 ) ) {
                     if ( ForkAvil [ philID ] . taken == 0 ) { //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION
                         ForkAvil [ philID ] . taken = Philostatus [ philID ] . right = 1 ;
                         printf ( "Fork %d taken by philosopher %d\n" , philID + 1 , philID + 1 ) ;
                     } else {
                         printf ( "Philosopher %d is waiting for fork %d\n" , philID + 1 , philID + 1 ) ;
                     }
                 } else { //except last philosopher case
                     int dupphilID = philID ;
                     philID -= 1 ;
                     if ( philID == - 1 )
                         philID = ( n - 1 ) ;
                     if ( ForkAvil [ philID ] . taken == 0 ) {
                         ForkAvil [ philID ] . taken = Philostatus [ dupphilID ] . right = 1 ;
                         printf ( "Fork %d taken by Philosopher %d\n" , philID + 1 , dupphilID + 1 ) ;
                     } else {
                         printf ( "Philosopher %d is waiting for Fork %d\n" , dupphilID + 1 , philID + 1 ) ;
                     }
                 }
             }
             else if ( Philostatus [ philID ] . left == 0 ) { //nothing taken yet
                     if ( philID == ( n - 1 ) ) {
                         if ( ForkAvil [ philID - 1 ] . taken == 0 ) { //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION
                             ForkAvil [ philID - 1 ] . taken = Philostatus [ philID ] . left = 1 ;
                             printf ( "Fork %d taken by philosopher %d\n" , philID , philID + 1 ) ;
                         } else {
                             printf ( "Philosopher %d is waiting for fork %d\n" , philID + 1 , philID ) ;
                         }
                     } else { //except last philosopher case
                         if ( ForkAvil [ philID ] . taken == 0 ) {
                             ForkAvil [ philID ] . taken = Philostatus [ philID ] . left = 1 ;
                             printf ( "Fork %d taken by Philosopher %d\n" , philID + 1 , philID + 1 ) ;
                         } else {
                             printf ( "Philosopher %d is waiting for Fork %d\n" , philID + 1 , philID + 1 ) ;
                         }
                     }
         } else { }
}
int main ( ) {
for ( i = 0 ; i < n ; i ++ )
         ForkAvil [ i ] . taken = Philostatus [ i ] . left = Philostatus [ i ] . right = 0 ;
while ( compltedPhilo < n ) {
/* Observe here carefully, while loop will run until all philosophers complete dinner
Actually problem of deadlock occur only thy try to take at same time
This for loop will say that they are trying at same time. And remaining status will print by go for dinner function
*/
for ( i = 0 ; i < n ; i ++ )
             goForDinner ( i ) ;
printf ( "\nTill now num of philosophers completed dinner are %d\n\n" , compltedPhilo ) ;
}
return 0 ;
}

Output

输出量

Fork 1 taken by Philosopher 1 Fork 2 taken by Philosopher 2 Fork 3 taken by Philosopher 3 Philosopher 4 is waiting for fork 3

哲学家1拿来的叉子1哲学家 2拿来的叉子2哲学家 3拿来的叉子3 哲学家4正在等待叉子3

Till now num of philosophers completed dinner are 0

到现在为止,有多少哲学家完成晚饭的人数是0

Fork 4 taken by Philosopher 1 Philosopher 2 is waiting for Fork 1 Philosopher 3 is waiting for Fork 2 Philosopher 4 is waiting for fork 3

哲学家1拿到的叉子4 哲学家2都在等待叉子1 哲学家3都在等待叉子2 哲学家4在等待叉子3

Till now num of philosophers completed dinner are 0

到现在为止,有多少哲学家完成晚饭的人数是0

Philosopher 1 completed his dinner Philosopher 1 released fork 1 and fork 4 Fork 1 taken by Philosopher 2 Philosopher 3 is waiting for Fork 2 Philosopher 4 is waiting for fork 3

哲学家1用餐完毕 哲学家1释放了叉子1和叉子4 哲学家2拿走了叉子1 哲学家3正在等待叉子2 哲学家4正在等待叉子3

Till now num of philosophers completed dinner are 1

到现在为止,有几位哲学家完成晚餐的人数是1

Philosopher 1 completed his dinner Philosopher 2 completed his dinner Philosopher 2 released fork 2 and fork 1 Fork 2 taken by Philosopher 3 Philosopher 4 is waiting for fork 3

哲学家1完成他的晚餐 哲学家2完成他的晚餐 哲学家2释放了叉子2和叉子1 哲学家3拿走的叉子2 哲学家4正在等待叉子3

Till now num of philosophers completed dinner are 2

到现在为止,有几位哲学家完成晚餐的人数是2

Philosopher 1 completed his dinner Philosopher 2 completed his dinner Philosopher 3 completed his dinner Philosopher 3 released fork 3 and fork 2 Fork 3 taken by philosopher 4

哲学家1完成他的晚餐 哲学家2完成他的晚餐 哲学家3完成他的晚餐 哲学家3释放了叉子3和叉子2 哲学家4拿走的叉子3

Till now num of philosophers completed dinner are 3

到现在为止,有多少位哲学家完成了晚餐3

Philosopher 1 completed his dinner Philosopher 2 completed his dinner Philosopher 3 completed his dinner Fork 4 taken by philosopher 4

哲学家1完成他的晚餐 哲学家2完成他的晚餐 哲学家3完成他的晚餐 叉子4由哲学家4采取

Till now num of philosophers completed dinner are 3

到现在为止,有多少位哲学家完成了晚餐3

Philosopher 1 completed his dinner Philosopher 2 completed his dinner Philosopher 3 completed his dinner Philosopher 4 completed his dinner Philosopher 4 released fork 4 and fork 3

哲学家1完成他的晚餐 哲学家2完成他的晚餐 哲学家3完成他的晚餐 哲学家4完成他的晚餐 哲学家4释放了叉子4和叉子3

Till now num of philosophers completed dinner are 4

到现在为止,有多少哲学家完成了晚餐4

用C ++解决餐饮哲学家问题的程序 (Program for Dining Philosophers Problem in C++)

Comment below if you have queries or found any information incorrect in above tutorial for dining philosophers problem in C and C++.

如果您对以上C和C ++中的用餐哲学家问题有疑问或发现任何不正确的信息,请在下面评论。

翻译自: https://www.thecrazyprogrammer.com/2017/06/dining-philosophers-problem-c-c.html

西方哲学史思维导图+脉络图