Process Synchronization Tools

Semaphores -- Concept and term come from old railroading days -- a critical section (to use CS term) is a section of shared track which should have no more than one train occupying it at a time.

Definitions

     wait(s):    while s <= 0 loop;
                   s = s - 1;       (enter, lower semaphore)

     signal(s):  s = s + 1;         (exit, raise semaphore)

Use in code

     repeat
       ...
       wait( mutex );
         critical section
       signal( mutex );
mutex is standard textbook semaphore name, for mutual exclusion. Each critical section will have its own variable name (mutex is a variable name).

To Avoid Busy Waits

More realistic code below. OS typically provides system calls (UNIX does, for example) so that they can be implemented efficiently. Efficient impl (i.e., to avoid busy waits) requires manipulation of ready and block queues.

    type semaphone = record
                       value:   integer;
                       L:       list of process ids;
                     end;

    wait(s):      s.value = s.value - 1;
                  if s.value < 0 then begin
                    add this process id to s.L;
                    insert_block( process id );
                  end;

    signal(s):    s.value = s.value + 1;
                  if s.value <= 0 then begin
                     remove some process p from s.L;
                     remove_block( p );
                     insert_ready( p );
                  end;

Implementation of `wait' and `signal' also has a critical section around changes to s.value. On a single processor system, you might turn off timer interrupts, so that changes to value are atomic. Since changes are fast (so that the timer interrupt will only be turned off for a very short period) this is acceptable.

Example: Bounded buffers using semaphores

Bounded buffer problem already discussed. Here's a solution using semaphores.
    Producer:                           Consumer:
    repeat forever                      repeat forever
      ...                                 ...
      produce item                        wait(full);
      wait(empty);                        wait(mutex);
      wait(mutex);                        ...
      ...                                 remove item from buffer
      add item to buffer                  signal(mutex);
      signal(mutex);                      signal(empty);
      signal(full);                       ...
      ...                               end
    end
Size of buffer is controlled by init value of empty. For a buffer of size 10, initialize empty to 10. full gets initialize to 0. Thus if consumer initially runs faster, is will get stopped at the wait(full) statement. If however the producer runs much faster than the consumer, it will get stopped at its wait(empty) statement, but only after it has cycled through its loop several times.

Example: Readers and writers

Several variations of this problem. Can usually have several readers in the critical section at the same time, but only one writer at a time. May give priority of writers to readers -- thus if a writer needs to enter critical section, with some versions of the problem, newly arriving readers should be blocked until the writer can enter and exit critical section. This is a tricky problem. It is also a real problem. Can easily to starvation of readers.

Dining Philosophers

A classical problem. Some number of philosophers spend time thinking and eating. Being poor, they must share a total of five chopsticks.

Rules:

  1. One chopstick between each philosopher
  2. Philosopher first picks up one (if it is available) then the second (if available)
  3. Only puts down chopsticks after eating for a while

Deadlock can occur, e.g., if all philosophers simultaneously pick up chopstick to his/her left.

Solutions:

  1. Allow only n-1 (if we have n chopsticks) at table
  2. Philosopher only picks up one chopstick if he/she can pick up both.
  3. Odd philosopher first picks up left, even philosopher first picks up right.


Tasking with Ada example code

Index Previous Next

Copyright ©2017, G. Hill Price
Send comments to G. Hill Price