Professional Documents
Culture Documents
3 - Hoare78 CSP
3 - Hoare78 CSP
Finally, some of it make sense. grams, three basic constructs have received widespread
How to edge detection?
How to create systolic array? recognition and use: A repetitive construct (e.g. the while
How to matrix multiplication?
How to how? loop), an alternative construct (e.g. the conditional
if..then..else), and normal sequential program composi-
Programming S. L. Graham, R. L. Rivest tion (often denoted by a semicolon). Less agreement has
Teclmiques Editors been reached about the design of other important pro-
4.4 Scanning a Set 4.6 Multiple Exits: Remove the Least Member
Problem: Extend the solution to 4.3 by providing a fast Exercise: Extend the above solution to respond to a
method for scanning all members of the set without command to yield the least member of the set and to
changing the value of the set. The user program will remove it from the set. The user program will invoke the
contain a repetitive command of the form: facility by a pair of commands:
5. Monitors and Scheduling However, after the producer has produced its next por-
tion, the consumer's request can be granted on the next
This section shows how a monitor can be regarded as iteration. (3) Similar remarks apply to the producer,
a single process which communicates with more than when in -- out + 10. (4) X is designed to terminate when
one user process. However, each user process must have out = in and the producer has terminated.
a different name (e.g. producer, consumer) or a different
subscript (e.g. X(0) and each communication with a user 5.2 Integer Semaphore
must identify its source or destination uniquely. Problem: To implement an integer semaphore, S, shared
Consequently, when a monitor is prepared to com- among an array X(i:I..100) of client processes. Each
municate with any of its user processes (i.e. whichever of process may increment the semaphore by S!V() or
them calls first) it will use a guarded command with a decrement it by S!P(), but the latter command must be
range. For example: .[(i:1.. 100)X(0?(value parameters) delayed if the value of the semaphore is not positive.
--~ ... ; X(0!(results)]. Here, the bound variable i is used Solution:
to send the results back to the calling process. If the S::val:integer; val .--- 0;
*[(i:I..100)X(0?V ( ) ~ val .--- val + 1
monitor is not prepared to accept input from some II(i:l..100)val > 0; X(0?P ( ) --, val ~ val - 1
particular user (e.g. X(j)) on a given occasion, the input ]
command may be preceded by a Boolean guard. For Notes: (1) In this process, no use is made of knowledge
example, two successive inputs from the same process of the subscript i of the calling process. (2) The sema-
are inhibited by j = 0; *[(i: 1.. 100)i # j; X(0?(values ) --, phore terminates only when all hundred processes of the
... ; j .--- i]. Any attempted outpui from X(j) will be process array X have terminated.
delayed until a subsequent iteration, after the output of
some other process X(i) has been accepted and dealt 5.3 Dining Philosophers (Problem due to E.W. Dijkstra)
with. Problem: Five philosophers spend their lives thinking
Similarly, conditions can be used to delay acceptance and eating. The philosophers share a common dining
of inputs which would violate scheduling constraints-- room where there is a circular table surrounded by five
postponing them until some later occasion when some chairs, each belonging to one philosopher. In the center
other process has brought the monitor into a state in of the table there is a large bowl of spaghetti, and the
which the input can validly be accepted. This technique table is laid with five forks (see Figure 1). On feeling
is similar to a conditional critical region [10] and it hungry, a philosopher enters the dining room, sits in his
obviates the need for special synchronizing variables own chair, and picks up the fork on the left of his place.
such as events, queues, or conditions. However, the Unfortunately, the spaghetti is so tangled that he needs
absence of these special facilities certainly makes it more to pick up and use the fork on his right as well. When he
difficult or less efficient to solve problems involving has finished, he puts down both forks, and leaves the
priorities--for example, the scheduling of head move- room. The room should keep a count of the number of
ment on a disk. philosophers in
Theit.
problem lies when all of the five philosophers arrive at the same
time --> The possibility of a deadlock because everyone would wait on
everyone.
Fig. 1.
5.1 Bounded Buffer
Problem: Construct a buffering process X to smooth
variations in the speed of output of portions by a pro-
ducer process and input by a consumer process. The
consumer contains pairs of commands X!more( );
X?p, and the producer contains commands of the form
X!p. The buffer should contain up to ten portions.
Solution:
(2
X::
buffer:(0..9) portion;
in,out:integer; in .--- 0; out .--- 0;
comment 0 <_ out _< in _< out + 10;
*[in < out + 10; producer?buffer(in mod 10) --* in .--- in + 1
[lout < in; consumer?more( ) --~ consumer!buffer(out rood 10); Solution: The behavior of the ith philosopher may be
out .--- out + 1 described as follows:
]
PHIL = *[... during ith lifetime ... ---,
Notes: (1) When out < in < out + 10, the selection of THINK;
the alternative in the repetitive command will depend on room!enter( );
fork(0!pickup( ); f o r k ( ( / + 1) rood 5)!pickup( );
whether the producer produces before the consumer
EAT;
consumes, or vice versa. (2) When out -- in, the buffer is fork(i)!putdown( ); f o r k ( ( / + 1) mod 5)!putdown( );
empty and the second alternative cannot be selected even room!exit( )
if the consumer is ready with its command X!more(). ]
0 0 0
6. M i s c e l l a n e o u s
~111 ~12x A13x
This section contains further examples of the use of
communicating sequential processes for the solution of
some less familiar problems; a parallel version o f the A11x*Azly A12x*A22y A13x*A23y
sieve o f Eratosthenes, and the design of an iterative
array. The proposed solutions are even more speculative
than those of the previous sections, and in the second A11x*A21y,A~ AlzX.A22Y.A3~AoX.A23y.A~z
example, even the question of termination is ignored.
p,rap:integer;
SIEVE(i- l)?p; The WEST and SOUTH borders are processes of the user
print!p; program; the remaining processes are:
rap .---p; c o m m e n t rap is a multiple o f p;
,[re:integer; S I E V E ( / - l)?m ---* N O R T H = .[true --* M(Id)!0 ]
*[m > mp ~ mp .--'- m p + p]; E A S T = .Ix:real; M(i,3)?x---> skip]
[m = rap --* skip C E N T E R = .[x:real; M(id - l)?x --*
nra < rap --* SIEVE(i + l)!ra M ( i , j + l)!x; sum:real;
] ] M ( i - l,j)?sum; M(i + l d ) ! ( A ( i , j ) * x + sum)
HSIEVE(0)::print!2; n:integer; n .--- 3; ]
* I n < 10000--* SIEVE(I)!n; n .--- n + 2]
IISIEVE(101)::*[n:integer;SIEVE(100)?n --~ print!n]
Hprint::,[(i:0.. 101) n:integer; SIEVE(0?n --> ...]
1 7. D i s c u s s i o n
Note: (1) This beautiful solution was contributed by
David Giles. (2) It is algorithmically similar to the A design for a programming language must neces-
program developed in [7, pp. 27-32]. sarily involve a number o f decisions which seem to be
674 Communications August 1978
of Volume 2 I
the A C M Number 8
fairly arbitrary. The discussion of this section is intended printed text which should describe the execution of the
to explain some of the underlying motivation and to program, independent of which parts were drawn from
mention some unresolved questions. a library.
Since I did not intend to design a complete language,
7.1 Notations I have ignored the problem of libraries in order to
I have chosen single-character notations (e.g. !,?) to concentrate on the essential semantic concepts of the
express the primitive concepts, rather than the more program which is actually executed.
traditional boldface or underlined English words. As a
result, the examples have an APL-like brevity, which 7.3 Port Names
some readers fred distasteful. My excuse is that (in An alternative to explicit naming of source and des-
contrast to APL) there are only a very few primitive tination would be to name a port through which com-
concepts and that it is standard practice of mathematics munication is to take place. The port names would be
(and also good coding practice) to denote common prim- local to the processes, and the manner in which pairs of
itive concepts by brief notations (e.g. +,x). When read ports are to be connected by channels could be declared
aloud, these are replaced by words (e.g. plus, times). in the head of a parallel command.
Some readers have suggested the use of assignment This is an attractive alternative which could be de-
notation for input and output: signed to introduce a useful degree of syntactically check-
able redundancy. But it is semantically equivalent to the
<target variable> := <source> present proposal, provided that each port is connected to
<destination> .---<expression>
exactly one other port in another process. In this case
I fend this suggestion misleading: it is better to regard each channel can be identified with a tag, together with
input and output as distinct primitives, justifying distinct the name of the process at the other end. Since I wish to
notations. concentrate on semantics, I preferred in this paper to use
I have used the same pair of brackets ([...]) to bracket the simplest and most direct notation, and to avoid
all program structures, instead of the more familiar raising questions about the possibility of connecting more
variety of brackets (if..fi, begin..end, case...esac, etc.). In than two ports by a single channel.
this I follow normal mathematical practice, but I must
also confess to a distaste for the pronunciation of words 7.4 Automatic Buffering
like fi, od, or esac. As an alternative to synchronization of input and
I am dissatisfied with the fact that my notation gives output, it is often proposed that an outputting process
the same syntax for a structured expression and a sub- should be allowed to proceed even when the inputting
scripted variable. Perhaps tags should be distinguished process is not yet ready to accept the output. An imple-
from other identifiers by a special symbol (say #). mentation would be expected automatically to interpose
I was tempted to introduce an abbreviation for com- a chain of buffers to hold output messages that have not
bined declaration and input, e.g. X?(n:integer) for yet been input.
n:integer; X?n. I have deliberately rejected this alternative, for two
reasons: (1) It is less realistic to implement in multiple
7.2 Expficit Naming disjoint processors, and (2) when buffering is required
My design insists that every input or output com- on a particular channel, it can readily be specified using
mand must name its source or destination explicitly. This the given primitives. Of course, it could be argued
makes it inconvenient to write a library of processes equally well that synchronization can be specified when
which can be included in subsequent programs, inde- required by using a pair of buffered input and output
pendent of the process names used in that program. A commands.
partial solution to this problem is to allow one process
(the main process) of a parallel command to have an 7.5 Unbounded Process Activation
empty label, and to allow the other processes in the The notation for an array of processes permits the
command to use the empty process name as source or same program text (like an Algol recursive procedure) to
destination of input or output. have many simultaneous "activations"; however, the
For construction of large programs, some more gen- exact number must be specified in advance. In a conven-
eral technique will also be necessary. This should at least tional single-processor implementation, this can lead to
permit substitution of program text for names defined inconvenience and wastefulness, similar to the fixed-
elsewhere--a technique which has been used informally length array of Fortran. It would therefore be attractive
throughout this paper. The Cobol coPY verb also permits to allow a process array with no a priori bound on the
a substitution for formal parameters within the copied number of elements; and to specify that the exact number
text. But whatever facility is introduced, I would rec- of elements required for a particular execution of the
ommend the following principle: Every program, after program should be determined dynamically, like the
assembly with its library routines, should be printable as maximum depth of recursion of an Algol procedure or
a text expressed wholly in the language, and it is this the number of iterations of a repetitive command.