1. Programming practice - the topic comes from Song Jinshan's "linuxc"
Philosopher dining problem. This is a classic deadlock scenario proposed by computer scientist Dijkstra.

There are five philosophers in the original story (but the program we wrote can have N philosophers). These philosophers only do two things - think and eat. They don't need any shared resources when thinking, but they have to use tableware when eating. The tableware on the table is limited. In the original story, the tableware is a fork, When eating, use two forks to take the noodles out of the bowl. Obviously, it would be more reasonable to replace a fork with chopsticks, so: a philosopher needs two chopsticks to eat.

Now the key to the problem is that these philosophers are very poor and can only afford five chopsticks. They sat in a circle with a chopstick between them. Philosophers must get both left-hand and right-hand chopsticks when eating. If anyone around him is using chopsticks, he has to wait.

Suppose the numbers of philosophers are A, B, C, D and E, and the numbers of chopsticks are 1, 2, 3, 4 and 5. The philosophers and chopsticks form A circle, as shown in the figure below:

Figure 35.2 Philosopher problem

Each philosopher is a separate thread. Each thread loops to do the following actions: think rand()%10 seconds, then take the left-hand chopsticks first, and then the right-hand chopsticks (chopsticks can be expressed as mutex). If you can't get them on either side, you'll wait all the time, eat rand()%10 seconds, and then put down the chopsticks.

Write a program to simulate the dining scene of philosophers:

```Philosopher A fetches chopstick 5
Philosopher B fetches chopstick 1
Philosopher B fetches chopstick 2
Philosopher D fetches chopstick 3
Philosopher B releases chopsticks 1 2
Philosopher A fetches chopstick 1
Philosopher C fetches chopstick 2
Philosopher A releases chopsticks 5 1
...```

Solution reference from https://blog.csdn.net/theLost...

```  1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<malloc.h>
4 #include<time.h>
5 #include<unistd.h>
7 #include<semaphore.h>
8
9 #define NUM 5
10
11 sem_t chopsticks[NUM];//sem_t semaphore parameter, which means that each fast chopstick can only be picked up by one person at most at the same time
12 sem_t r;//When picking up the semaphore parameters of the left chopsticks, only four people can pick up the left chopsticks at the same time, otherwise they will have a life and death lock
13 int philosophers[NUM] = {0,1,2,3,4};//Philosopher array, representing 5 Philosophers 0,1,2,3,4,
14
15 pthread_mutex_t chops[NUM];//Mutex is the control variable of the lock
16
17 //int Islocked[NUM] = {0};// The array of control variables needed to implement the mutex
18 //When multiple threads call the usual swap function at the same time, it is easy to produce instruction misdirection, which will affect the result
19 //The instruction set of intel X86 provides the instruction xchg to exchange two numbers, and the register control will not be concurrent
20 //void xchg(int *x,int *y) {/ / exchange instruction in assembly
21 //    __asm__("xchgl %0, %1" : "=r" (*x) : "m" (*y));
22 //}
23
24 //Core function (use semaphore to control up to 4 people to pick up left chopsticks to prevent deadlock)
25 void *philosopher(void *arg){//arg is passed from the fourth parameter of the init function
26     int i = *((int *)arg);//i stands for the ith philosopher
27     int left = i;//Set the chopsticks on the left as i
28     int right = (i+1)%NUM;//Circular queue structure, set chopsticks on the right as i+1
29     //int leftkey;// The key variable required to implement the left mutex
30     //int rightkey;// The key variable needed to implement the right mutex
31     while(1){
32        //leftkey = 1;
33        //rightkey = 1;
34
35         printf("philosopher%d Thinking\n",i);
36         sleep(rand()%NUM);//The process was suspended for some time and the representative thought for a while
37
38         printf("philosopher%d Hungry\n",i);
39
40         sem_wait(&r);//Semaphore R - 1 (if r=0, wait is suspended; if r > 0, thread resources can be obtained to perform subsequent operations, and R will not be < 0)
41         sem_wait(&chopsticks[left]);//Note that there is only one semaphore per chopsticks
43         //do{
44            //xchg(&leftkey,&Islocked[left]);// At this time, the leftkey is not 1, and 1 will be exchanged to islocked [left]
45             //So when the second thread comes in, it will block in do_ The while loop locks critical resources. mutex function in linux
46         //}while(leftkey);
47         printf("philosopher%d Picked it up%d No. chopsticks,Now there is only one chopstick,No meals\n",i,left);
48
49         //do{
50             //xchg(&rightkey,&Islocked[right]);
51         //}while(rightkey);
52         sem_wait(&chopsticks[right]);
54         printf("philosopher%d Picked it up%d No. chopsticks,Now there are only two chopsticks,Start eating\n",i,right);
55         sleep(rand()%NUM);//The process is suspended for a period of time, which represents the end of eating for a period of time
56
57         //Islocked[left] = 0;// At present, the second thread can enter after the execution of a signal to take the left chopstick
58         sem_post(&chopsticks[left]);
60         printf("philosopher%d Put it down%d No. chopsticks\n",i,left);
61
62         //Islocked[right] = 0;// At present, the second thread can enter after the execution of a signal to take the left chopstick
63         sem_post(&chopsticks[right]);
65         printf("philosopher%d Put it down%d No. chopsticks\n",i,right);
66
67         sem_post(&r);//Release the resource, semaphore + 1, so you can wake up the thread waiting for semaphore > 0 at the same time
68
69     }
70 }
71 int main(int argc,char **argv){
72     srand(time(NULL));
74
75     int i= 0;
76     for(i = 0;i < NUM; i++){
77         sem_init(&chopsticks[i],0,1);//Semaphore initialization, each chopstick can only be picked up once at the same time
78     }
79     sem_init(&r,0,4);//The semaphore control variable r controls that the signal of picking up the left chopsticks at the same time cannot exceed 4
80
81     int j = 0;
82     for(j = 0; j < NUM; j++){
84     }
85
86     int k = 0;
87     for(k = 0; k < NUM; k++){
89     }
90
91     int l = 0;
92     for(l = 0; l < NUM; l++){
93         pthread_join(PHD[l],NULL);//Wait for each thread to terminate, change these threads from termination state to detach state, and recover the resources occupied by the threads
94     }
95
96     int m = 0;
97     for(m = 0; m < NUM; m++){
98         sem_destroy(&chopsticks[m]);//Release semaphore related resources occupied by variables
99     }
100     sem_destroy(&r);//As above, release the semaphore resources occupied by the left chopstick monitoring
101
102     int n = 0;
103     for(n = 0; n < NUM; n++){
104         pthread_mutex_destroy(&chops[n]);//Destroy mutex and release resources
105     }
106
107     return 0;
108 }
```

I use mutex to realize mutex in linux environment. In windows environment, the annotated while do while loop can be used to simulate mutex, which can also run successfully and get results!