2

I found a solution to the mutual-exclusion problem online that has two processes P0 and P1. (Assume that the variable turn is initialized to 0)

volatile int turn;  

Process P0:

/* Other code */
  while (turn != 0) { } /* Do nothing and wait. */
  Critical Section /* . . . */
  turn = 1;
  /* Other code */

Process P1:

/*Other code*/
  while (turn != 1) { } /* Do nothing and wait. */
  Critical Section /* . . . */
  turn = 0;
  /* Other code */

How does this solution solve the mutual-exclusion problem? I don't understand it fully.

ZhongYu
  • 19,446
  • 5
  • 33
  • 61
Tia
  • 27
  • 3

3 Answers3

1

Assuming there's no other code that can set turn to a value other than 0 or 1, and assuming the only thing messing with the turn variable are P0 and P1, then this does solve the mutual exclusion property. Specifically, you say that turn is initialized to 0. So that means P1 can't enter the critical section: it's busy in the while (turn != 1) loop and it'll stay in that loop until something sets turn == 1. Given our assumption that only P0 and P1 make changes to turn that means P1 can't enter the critical section until P0 sets turn to 1. So P0 will immediately exit it's while (turn != 0) loop (as turn is initially 0) and safely enter its critical section. It knows P1 can't enter it's critical section until turn gets set to 1 and that only happens after P0 has left it's critical section. Once P0 sets turn to 1, P0 will be stuck in it's while (turn != 0) loop until P1 sets it free so now P1 is in it's critical section and P0 can't be in it's. And so on.

An easy way to think of this is two people and a batton. They each agree not to do anything (enter their critical section) unless they hold the batton. So Person 1 has the batton at first and is free to do stuff knowing that Person 2 can't do anything - they don't have the batton. Once Person 1 is done, they hand the batton to Person 2. Person 2 is now free to do whatever they want and they know Person 1 is doing nothing but waiting for the batton to be handed back to them.

Oliver Dain
  • 9,617
  • 3
  • 35
  • 48
0

As @JustinSteele points out, this definitely does not solve the mutual exclusion problem. Maybe if you would change the turn to a boolean, you could get a dirty fix, since a boolean only consists out of two values. If you want a more proper way of providing mutual exclusive, I would suggest to take a look at mutexes, semaphores and condition variables. Good luck!

  • Oliver did state the assumption that turns can be either 0 or 1. But yeah, sorry I wasn't clear about that! – Tia Nov 04 '15 at 19:23
0

If both P0 and P1 are executed, and each is executed only once, it is true that P0 will enter the critical section first, exclusively, before P1 does.

In term of Java Memory Model, this program is correctly synchronized, because all inter-thread actions are volatile reads and writes. Therefore the program is sequentially consistent, easy to analyze.

Or, more specifically, all volatile reads and writes are in a total order (that's consistent with the programming order); this order will guarantee the mutual exclusiveness of critical sections.


However, there is a serious problem here. If P1 arrives first, it must wait for P0, no matter how late P0 arrives. This is quite unfair. And, if P0 is not executed, P1 cannot advance. And, If P0 is executed and P1 is not, P0 cannot enter the critical section again (it must wait for P1 to reset the turn). This locking mechanism only allows a strict P0-P1-P0-P1-... sequence (unless that is exactly what's desired)

To solve this problem, there are Dekker's algorithm, Peterson's algorithm, etc. See this post - https://cs.stackexchange.com/a/12632

Community
  • 1
  • 1
ZhongYu
  • 19,446
  • 5
  • 33
  • 61