Goal is to provide programming tools which reduce the likelihood of errors for this type of code. The idea is that if the compiler writer can get the process synchronization code right, then code using that language will be much less error-prone.
Critical Regions:
Code example:
code fragment 1: code fragment 2:
VAR v: SHARED type; VAR v: SHARED type;
... ...
REGION v DO s1; REGION v DO s2;
The compiler then generates the code to insure that s1 and s2 are not executed simultaneously, e. g.,
/
| ...
| wait( v_mutex );
REGION v DO s; < s;
| signal( v_mutex );
| ...
\
Critical region solution is not foolproof. Consider
code fragment 1: code fragment 2:
... ...
REGION x DO REGION y DO
... ...
REGION y DO REGION x DO
s1; s2;
(i.e., deadlock can occur).
Another example, but this time using conditional critical regions.
Here is a solution to the bounded buffer problem using conditional critical regions:
VAR buffer SHARED RECORD
pool: ARRAY[ 1..n-1 ] OF item;
count, in, out: integer;
END;
producer:
REGION buffer WHEN count < n DO BEGIN <--- this means that the
pool[ in ] := nextp; process cannot enter
in := in + 1 MOD n; the region unless the
count := count + 1 condition is true. This
END; is in addition to the
mutual exclusion normally
consumer: provided by regions.
REGION buffer WHEN count > 0 DO BEGIN
nextc := pool[ out ];
out := out + 1 MOD n;
count := count -1
END;
This provides a neat, simple, elegant solution to the problem.
(A historical comment: the problem with providing these types of language constructs to simplify code has not really caught on. The problem is not creating new compilers for new languages -- this process is well understood. The problem is that the next process synchronization problem is likely to have some unique feature so that the provided language construct, such as conditional critical regions, does not handle well. And the code gets confusing and complex and hence error-prone all over again.)
Monitors
Another attempt to reduce errors.
Example: Dining Philosophers. This implements the "grab both chopsticks" solution.
Each Philosopher:
REPEAT forever
wait( rnd( thinktime ) );
dp.pickup( i );
wait( rnd( eattime ) );
dp.putdown( i );
END;
Monitor Code:
TYPE dp = MONITOR
VAR state: ARRAY[ 0..4 ] OF ( thinking, hungry, eating );
VAR self: ARRAY[ 0..4 ] OF condition; { only ops on condition var }
{ are wait and signal }
PROC pickup( i: 0..4 );
BEGIN
state[ i ] := hungry;
test[ i ];
IF state[ i ] <> eating THEN self[ i ].wait;
END;
PROC putdown( i: 0..4 );
BEGIN
state[ i ] := thinking;
test[ i+4 MOD 5 ];
test[ i+1 MOD 5 ];
END;
PROC test( k: 0..4 );
BEGIN
IF state[ k+4 MOD 5 } <> eating
AND state[ k+1 MOD 5 ] <> eating
AND state[ k ] = hungry
THEN BEGIN
state[ k ] := eating;
sefl[ k ]. signal;
END
END;
BEGIN { init }
FOR i := 0 TO 4 DO
state[ i ] := thinking
END;
Note: starvation (pun intented) is possible with this solution.
| Index | Previous | Next |
|---|
Copyright ©1998, G. Hill Price
Send comments to G. Hill Price