A 5-Philosopher's dining problem
Semaphore fork[5];
for (int i=0;i<5;i++)
fork[i]=1;
Cobegin
Process Philosopher_i () { //i= 0,1,2,3,4
while (true) {
think ();
P (Fork[i]); First-hand fork
P (fork[(i+1)%5]); Then take the left hand fork
eat ();
V (Fork[i]);
V (fork[(i+1)%5]);
}
}
Coend
This solution will cause a deadlock.
To avoid deadlocks
1. Allow up to four philosophers to fetch forks at a time
2. The odd number first takes the fork on the left hand side, the even number first takes the right hand side fork
3. Each philosopher takes two forks at hand to eat, or a fork does not take
Semaphore fork[5];
for (int i=0;i<5;i++)
fork[i]= 1;
Semaphore room=4; Add a waiter
cobegin
process Philosopher_i () {/*i=0,1,2,3 */
while (true) {
think ();
P (guest); control allows up to 4 for philosophers to fetch fork
P (fork[i];
P (fork[(i+1)%5]);
Eat ();
V (Fork[i]);
V (Fork ([i+ 1]% 5);
V (guest);
}
}
Coend
void philosopher (int i)
{ If i mod 2==0 then
{
P (fork[i]); Even philosophers first right hand
P (fork[(i+1) mod 5]); Rear left hand
eat ();
V (Fork[i]);
V (fork[(i+1) mod 5]);
}
else
{
P (fork[(i+1) mod 5]);//Odd philosopher, first left hand
P (Fork[i]); After right hand
eat ();
V (fork[(i+1) mod 5]);
V (Fork[i]);
}
}
Semaphore fork[5];
for (int i=0;i<5;i++)
fork[i]= 1;
Cobegin
Process Philosopher_i () {/*i=0,1,2,3 */
while (true) {
think ();
P (fork[i];//first-hand fork /*i=4,p (fork[0]) *
/P (fork[(i+1)%5]);//fork with left hand/*i=4,p (fork[4]) */
eat ();
V (Fork[i]);
V (Fork ([i+ 1]% 5);
}
}
Coend
Solving philosophers ' problems by Hoare tube process
Detailed
Type dining_philosophers=monitor
int self_count[5];
Interfacemodule IM;
for (int i=0;i<5;i++) /Initialize, I is the process number
state[i]=thinking;
Define Pickup,putdown;
Use enter,leave,wait,signal;
void Pickup (int i) { //i=0,1,..., 4
Enter (IM);
State[i]=hungry;
Test (i);
if (state[i]!=eating)
wait (self[i],self_count[i],im);
Leave (IM);
}
void putdown (int i) { //i=0,1,2,.., 4
Enter (IM);
state[i]=thinking;
Test ((i-1)%5);
Test ((i+1)%5);
Leave (IM);
}
void Test (int k) { //k=0,1,..., 4
if (state[(k-1)%5]!=eating) && (state[k]==hungry)
&& (state[(k+1)%5]!=eating)) {
state[k]=eating;
Signal (SELF[K],SELF_COUNT[K],IM);
}}} Any philosopher who wants to eat the pickup, invokes the procedure, and then calls the process putdown after eating through the heart surface.
cobegin
Process Philosopher_i () { //i=0,..., 4
while (true) {
thinking ();
Dining_philosophers.pickup (i);
Eating ();
Dining_philosophers.putdown (i);
}
}
Coend
(a) assuming that at the beginning of the 3rd philosopher, the first to do pickup, he would be very smooth, in the pickup through enter (IM) into the pipe, modify its own state state[3]=hungry, and then test (3) in the If condition through, modify its own state state[3]= Eating, because there is no process (philosopher) blocking on self[3], that is, self_count[3]==0, control signal (Self[3], self_count[3], IM) in the implementation of PV, in fact, at this time signal do nothing. The IF (state[3]!=eating) is then judged not to be true, so the wait operation is not done. Then, the 3rd philosopher executes leave (IM) to exit the tube, so that other philosophers can enter the pipe process.
Analysis: In fact, the 3rd philosopher here successfully took the two forks he needed. By changing his state to eating, the philosopher i=2 had to do test (i) when he took the fork, and State[i+1]!=eating was not established; for the i=4 philosopher, when taking the fork, test (i), state[i-1]!= Eating is not established; the philosopher turned to eating state, 2, 4th philosopher cannot successfully transfer to eating state, will perform the wait operation, that is, the 3rd philosopher did not execute putdown in the test ((i-1)%5) and test ((i+1)%5 Before, left and right philosophers could not successfully fetch a fork.
(B) Then, before the philosopher 3rd had putdown, if the philosopher 1th executed pickup, he would be very smooth, similar to the case of the previous philosopher 3rd pickup, and enter the tube in pickup by entering Modify its own state state[1]=hungry, then test (1) in the IF condition through, modify its own state state[1]=eating, because there is no process (philosopher) blocked on self[1], that is Self_count [1]==0, in contrast to signal (SELF[1],&NBSP;SELF_COUNT[1],&NBSP;IM) in the implementation of PV, in fact, at this time signal do nothing. Then, Judge if (state[1]!=eating) is not established, so the wait operation is not done. Then, the 3rd philosopher executes leave (IM) to exit the tube, so that other philosophers can enter the pipe process.
Analysis: In fact, the 1th philosopher here successfully took the two forks he needed. By changing his state to eating, he blocked the philosopher's transition to eating state, and the philosopher 0 and 2nd could not successfully transfer to eating state, that is, the philosopher 1th did not perform putdown test ((i-1)%5) and test ((i+1)%5) Previously, the fork could not be successfully taken.
(C) Then, before the philosophers of 1 and 3rd did not putdown, at this time, state[1]==eating,state[3]==eating. If the 2nd philosopher executes pickup, he will be very uncomfortable, enter the tube through enter (IM) in pickup, modify its own state state[2]=hungry, and then test (2) The IF condition state[1]!=eating,state[3]! =eating is not established, so the 2nd philosopher did not successfully change their state to eating, do not have to do test (2) signal (SELF[2],&NBSP;SELF_COUNT[2],&NBSP;IM) operation, and then Judge if (state[2]!=eating) is established, so do wait (Self[2], self_count[2], im) operation, against the wait operation of the PV implementation, at this time, self[2]_count++ expressed in self[2 ] Wait for the number of processes plus 1, and then Judge if (im.next_count>0), if at this time the 1 and 3rd processes do not perform signal operations in putdown, then the condition is not established, then execute V (im.mutex) exit the pipe, then P ( SELF[2]) block themselves, waiting for the 1 and 3rd philosophers to perform putdown in the wake of the signal operation.
(D) Then, assuming that philosopher 1th finishes eating, executes putdown, enters the tube through enter (IM) in putdown, modifies its own state state[1]=thinking, and then test (i-1)%5, which is test (0), where state[(0-1)%5] namely State[4]!=eating was established, State[0]==hungry was not established (indicating that philosopher No. 0 did not perform pickup), state[(0+1)%5] namely State[1]!=eating was established, That is, the entire if condition is not established, if the statement does not do. Then test ((i+1)%5), which is Test (2), where state[(2-1)%5] is state[1]!=eating established, state[2]==hungry (indicating that the previous philosopher 2nd had executed pickup and did not successfully fetch the fork), state[(2+1)%5] i.e. state[3]!=eating not established, that is, the entire if condition is still not established, then the 1th philosopher performs leave (IM) to exit the tube, so that other philosophers can enter the tube process.
Analysis: 1 in putdown, test (0) and test (2), test (0) is intended to wake the right neighbor philosopher No. 0, but the No. 0 philosopher has not executed pickup, and has not changed its state to hungry, The kindness of philosopher 1th was wasted; then test (2) was intended to awaken the left neighbor philosopher 2nd, but the 2nd philosopher had to judge whether the number 3rd was eating before he successfully took the fork, and in fact at this point 3rd was still eating, so the intent of test (2) was not really successful. It seems really not easy, it doesn't matter, continue to look down.
(E) when philosopher 1th exits the tube in putdown, state[1]==thinking,state[2]==hungry at this point, assume that at this point the philosopher 3rd begins to execute putdown, and in Putdown through enter (IM ) into the tube and modify its own state state[3]=thinking, then test ((i-1)%5), i.e. test (2), where state[(2-1)%5] is state[1]!=eating established, State[2]==hungry established (indicating that the previous 2nd philosopher had executed the pickup, and did not successfully fetch the fork), state[(2+1)%5] namely State[3]!=eating was established, that is, the entire if condition, see hope, then execute signal (self[2], Self_count[2], im), because the philosopher 2nd had been waiting for a long time on the self[2], with the signal operation of the PV implementation, self_count[2]>0, execution im.next_count++,v (self [2]) (note: Self[2, who finally waited for the 2nd philosopher), awakened the philosopher 2nd, and P (Im.next) blocked himself.
Analysis: After the 2nd philosopher is awakened, he will execute the statement after his pickup in P (self[2]), self_count[2]--, i.e. self_count[2] revert to 0, and eventually execute pickup leave (IM), In Leave (IM) refer to the PV implementation of the Hoare enhancement leave operation, judging if (Im.next_count) >0 is established, then execute V (im.next) Wake up 3rd philosopher before on P (im.next) Wait, and have the opportunity to execute the subsequent statement im.next_count--, that is, the count reverts to 0, the final execution putdown in leave (IM) exit the pipe, so that other processes can re-enter the pipe, here can be seen for the Hoare tube implementation, The signal operation does not have to be the last action of the procedure body. For the 3rd philosopher by Test (2) completed the task of awakening the philosopher 2nd, but he himself temporarily blocked on the Im.next, temporarily unable to execute putdown in the subsequent test ((i+1)%5), that is, cannot execute test (4).
(F) Then, assuming that the 2nd philosopher was awakened to the fork and began to eat, the philosopher 3rd executed the leave (IM) exit in Putdown, and if the philosopher 1th wanted to take the fork again, this time state[0]==state[3]==thinking,state[ 2]==eating,1 is not as smooth as before, in the pickup through enter (IM) into the pipe, modify its own state state[1]=hungry, and then test (1), state[2]!=eating is not established, that is, if condition does not pass, Therefore, the 1th philosopher did not successfully change its state to eating, and did not do the test (1) signal (self[1], self_count[1], IM) operation, and then judged if (state[1]!=eating) is established, so do wait ( SELF[1], self_count[1], IM) operation, compared to the PV implementation of the wait operation, at this time, self[1]_count++ represents the number of processes waiting in self[1] plus 1, and then determine if (im.next_count>0), If at this point the 2nd process has not yet performed the signal operation in Putdown, then the condition is not established, then execution V (im.mutex) exits the pipe, then P (self[1]) blocks itself, waiting for the 2nd philosopher to perform the putdown operation in signal wake.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++
Ii. Producer and consumer issues
Multiple producers/multiple consumers/multiple buffer units
B:array[0..k-1] of Integer;
Sput:semaphore;/ * The number of empty buffers that can be used */
sget:semaphore; /* Number of products that can be used in the buffer *
/sput: = k; /* buffer allowed to put K-pieces of products *
/sget: = 0; /* No products in buffer */
putptr, Getptr:integer;
Putptr: = 0; GetPtr: = 0;
S:semaphore;/ * Mutex use putptr, GetPtr *
/s: = 1;
process Producer_i
begin
L1:produce a product;< C16/>p (sput);
P (S1);
B[PUTPTR]: = Product;
putptr: = (putptr+1) mod k;
V (S1);
V (sget);
Goto L1;
End;
Process Consumer_ J
begin
L2:p (sget);
P (S2);
product:= b[getptr];
getptr:= (getptr+1) mod k;
V (S2);
V (sput);
Consume a product;
goto L2;
End
It is important to note that the order of two P operations cannot be reversed, both in the producer process and in the consumer process.
The p operation of the synchronous semaphore should be performed before executing the p operation of the mutex semaphore, which could cause a process deadlock.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Third, reader writing questions
Written by first:
Semaphore rmutex,wmutex,s;
rmutex=1; wmutex=1; S=1; Increase the mutex semaphore S
int readcount=0;//Read process count process
Reader_i ( )
{while (true) {
P (S);
P (Rmutex);
if (readcount==0) P (Wmutex);
readcount++;
V (Rmutex);
V (S);
Read the document;
P (Rmutex);
readcount--;
if (readcount==0) V (Wmutex);
V (Rmutex);
}
}
Process Writer_i ( ) {
while (true) {
P (S);
P (Wmutex);
Write a file;
V (Wmutex);
V (S);
}
}
int readcount = 0, writecount = 0;
Semaphore X=1, Y=1, z=1; Readcount,writecount Mutex
semaphore rmutex=1,wmutex=1; //Read lock, write lock
process reader
{
P (z);
P (Rmutex);
P (x);
Readcoun