Concepts and Notations For Concurrent Programming PDF
Concepts and Notations For Concurrent Programming PDF
GREGORY R. ANDREWS
Department of Computer Science, University of Arizona, Tucson, Arizona 85721
FRED B. SCHNEIDER
Department of Computer Science, Cornell University, Ithaca, New York 14853 .
Much has been learned in the last decade about concurrent programming..This patmr
identifies the major concepts of concurrent programming and describes some of the more
importam language notations for writing concurrent programs. The roles of processes,
communication, and synchronization are discussed. Language notations for expressing
concurrent execution and for specifying process interaction are surveyed. Synchronization
primitives based on shared variables and on message passing are described. Finally, three
general classes of concurrent programming languages are identified and compared.
Permission to copy without fee all or part of this material is granted provided that the copies are not made or
distributed for direct commercial advantage, the ACM copyright notice and the title of the publication and its
dateappear, and notice is given that copying is by permission of the Association for Computing Machinery. To
copy otherwise, or to republish, requires a fee and/or specific permission.
© 1983 ACM 0010-4892/83/0300-0003 $00.75
tions network. 1 Hybrid approaches also ex- buffer is used for communication between
i s t - f o r example, processors in a distributed the reader process and the executer proc-
system are often multiprogrammed. ess. These processes must be synchronized
The rate at which processes are executed so that, for example, the executer process
depends on which approach is used. When never attempts to read a card image from
each process is executed on its own pro- the input if the buffer is empty.
cessor, each is executed at a fixed, but per- This view of synchronization follows
haps unknown, rate; when processes share from taking an operational approach to
a processor, it is as if each is executed on program semantics. An execution of a con-
a variable-speed processor. Because we current program can be viewed as a se-
would like to be able to understand a con- quence of atomic actions, each resulting
current program in terms of its component from the execution of an indivisible opera-
sequential processes and their interaction, tion. 2 This sequence will comprise some
without regard for how they are executed, interleaving of t h e sequences of atomic ac-
we make no assumption about execution tions generated by the individual compo-
rates of concurrently executing processes, nent processes. Rarely do all execution in-
except that they all are positive. This is terleavings result in acceptable program be-
called the finite progress assumption. The havior, as is illustrated in the following.
correctness of a program for which only Suppose initially t h a t x ffi 0, that process
finite progress is assumed is thus independ- P1 increments x by 1, and that process P2
ent of whether that program is executed on increments x by 2:
multiple processors or on a single multipro- PI: x :ffix + 1 P2: x:-- x + 2
grammed processor.
It would seem reasonable to expect the final
1.2 Process Interaction value of x, after P1 and P2 have executed
In order to cooperate, concurrently execut- concurrently, to be 3. Unfortunately, this
ing processes must communicate and syn- will not always be the case, because assign-
chronize. Communication allows execution ment statements are not generally imple-
of one process to influence execution of mented as indivisible operations. For ex-
another. Interprocess communication is ample, the above assignments might be
based on the use of shared variables (vari- implemented as a sequence of three indi-
ables that can be referenced by more than visible operations: (i) load a register with
one process) or on message passing. the value of x; (ii) add 1 or 2 to it; and (iii)
Synchronization is often necessary when store the result in x. Thus, in the program
processes communicate. Processes are exe- above, the final value of x might be 1, 2, or
cuted with unpredictable speeds. Yet, to 3. This anomalous behavior can be avoided
communicate, one process must perform by preventing interleaved execution of the
some action that the other detects--an ac- two assignment statements--that is, by
tion such as setting the value of a variable controlling the ordering of the" events cor-
or sending a message. This only works if responding to the atomic actions. (If order-
the events "perform an action" and "detect ing were thus controlled, each assignment
an action" are constrained to happen in statement would be an indivisible opera-
that order. Thus one can view synchroni- tion.) In other words, execution of 1)1 and
zation as a set of constraints on the ordering P2 must be synchronized by enforcing re-
of events. The programmer employs a syn- strictions on possible interleavings.
chronization mechanism to delay execu- The axiomatic approach [Floyd, 1967;
tion of a process in order to satisfy such Hoare, 1969; Dijkstra, 1976] provides a sec-
constraints.
To make the concept of synchronization 2 W e assume t h a t a single m e m o r y reference is indivi-
a bit more concrete, consider the batch sible; ff two processes a t t e m p t to reference the same
m e m o r y cell at t h e same time, t h e result is as if t h e
operating system described above. A shared references were m a d e serially. This is a reasonable
assumption in light of the way m e m o r y is constructed.
1A concurrent program that is executed in this way is See L a m p o r t [19801)] for a discussion of some of t h e
often called a distributed program. implications of relaxing this assumption.
call `4;
yco?n.ne
resume B;
end
r e s u m e .4;
resume B ~ ...
return
end.
Figure 2. Outline of batch operating system.
mented; otherwise the descriptor for the since mutually exclusive execution would
executing process is moved to the s e m a - no longer be ensured. Also, when using
p h o r e ' s queue. For a V operation, if the semaphores, a programmer can forget to
semaphore's queue is not empty, one de- include in critical sections all statements
scriptor is moved from that queue to the that reference shared objects. This, too,
ready list; otherwise the semaphore is in- could destroy the mutual exclusion re-
cremented. quired within critical sections. A second
This approach to implementing synchro- difficulty with using semaphores is that
nization mechanisms is quite general and is both condition synchronization and mutual
applicable to the other mechanisms that we exclusion are programmed using the same
shall discuss. Since the kernel is responsible pair of primitives. This makes it difficult to
for allocating processor cycles to processes, identify the purpose of a given P or V
it can implement a synchronization mech- operation without looking at the other op-
anism without using busy-waiting. It does erations on the corresponding semaphore.
this by not running processes that are Since mutual exclusion and condition syn-
blocked. Of course, the names and details chronization are distinct concepts, they
of the kernel calls will differ for each syn- should have distinct notations.
chronization mechanism, but the net effects The c o n d i t i o n a l critical region proposal
of these calls will be similar: to move pro- [Hoare, 1972; Brinch Hansen 1972, 1973b]
cesses on and off a ready list. overcomes these difficulties by providing a
Things are somewhat more complex structured notation for specifying synchro-
when writing a kernel for a multiprocessor nization. Shared variables are explicitly
or distributed system. In a multiprocessor, placed into groups, called resources. Each
either a single processor is responsible for shared variable may be in at most one
maintaining the ready list and assigning resource and may be accessed only in con-
processes to the other processors, or the ditional critical region (CCR) statements
ready list is shared [Jones and Schwarz, that name the resource. Mutual exclusion
1980]. If the ready list is shared, it is subject is provided by guaranteeing that execution
to concurrent access, which requires that of different CCR statements, each naming
mutual exclusion be ensured. Usually, busy- the same resource, is not overlapped. Con-
waiting is used to ensure this mutual exclu- dition synchronization is provided by ex-
sion because operations on the ready list plicit Boolean conditions in CCR state-
are fast and a processor cannot execute any ments.
process until it is able to access the ready A resource r containing variables vl,
list. In a distributed system, although one v 2 , . . . , v N is declared as 13
processor could maintain the ready list, it r e s o u r c e r: v l , v2, . . . . vN
is more common for each processor to have
its own kernel and hence its own ready list. The variables in r may only be accessed
Each kernel manages those processes resid- within CCR statements that name r. Such
ing at one processor; if a process migrates statements have the form
from one processor to another, it comes
region r when B do S
under the control of the other's kernel.
where B is a Boolean expression and S is a
3.3 Conditional Critical Regions statement list. (Variables local to the exe-
cuting process may also appear in the CCR
Although semaphores can be used to pro- statement.) A CCR statement delays the
gram almost any kind of synchronization, P executing process until B is true; S is then
and V are rather unstructured primitives, executed. The evaluation of B and execu-
and so it is easy to err when using them. tion of S are uninterruptible by other CCR
Execution of each critical section must be- statements that name the same resource.
gin with a P and end with a V (on the same
semaphore). Omitting a P or V, or acciden-
tally coding a P on one semaphore and a V ~3Our notation combines aspects of those proposed by
on another can have disastrous effects, Hoare [1972] and by Brinch Hansen [1972, 1973b].
cond.wait
ComputingSurveys,"Col.15,No. 1,March1983
Concepts and Notations for Concurrent Programming• " 19
. . . . f~:, ?- •~,•
that it might be able to proceed. 17 There- tion called the m o n i t o r invariant. This
fore, in Mesa one writes predicate should be true of the monitor's
permanent variables whenever no process
while not B do wait cond endloop
is executing in the monitor. Thus a process
instead of must reestablish the monitor invariant be-
fore the process exits the monitor or per-
if not B then cond.wait
forms a w a i t ( d e l a y ) or signal(continue).
as would be done using Hoare's condition The monitor invariant can be assumed to
variables. Boolean condition B is guaran- be true of the permanent variables when-
teed to be true upon termination of the ever a process acquires control of the mon-
loop, as it was in the two conditional-wait/ itor, regardless of whether it acquires con-
automatic-signal proposals. Moreover, the trol by calling a monitor procedure or by
(possible) repeated evaluation of the Boo- being reactivated following a w a i t or sig-
lean expression appears in the actual mon- nal.
itor code--there are no hidden implemen- The fact that monitor procedures are
tation costs. mutually exclusive simplifies noninterfer-
The n o t i f y primitive is especially useful ence proofs. One need not consider inter-
if the executing process has higher priority leaved execution of monitor procedures.
than the waiting processes. It also allows However, interference can arise when pro-
the following extensions to condition vari- gramming condition synchronization. Re-
ables, which are often useful when doing call t h a t a process will delay its progress in
systems programming: order to implement medium-term schedul-
ing, or to await some condition. Mecha-
(i) A time-out interval t can be associated nisms that delay a process cause its execu-
with each condition variable. If a pro- tion to be suspended and control of the
cess is ever suspended on this condition monitor to be relinquished; the process re-
variable for longer than t time units, a sumes execution with the understanding
notify is automatically performed by that both some condition B and the moni-
the system. The awakened process can tor invariant will be true. The truth of B
then decide whether to perform an- when the process awakens can be ensured
other w a i t or to take other action. by checking for it automatically or by re-
(ii) A b r o a d c a s t primitive can be defined. quiring that the programmer build these
Its execution causes all processes wait- tests into the program. If programmed
ing on a condition variable to resume checks are used, they can appear either in
at some time in the future (subject to the process that establishes the condition
the mutual exclusion constraints asso- (for condition variables and queues) or in
ciated with execution in a monitor). the process that performed the wait (the
This primitive is useful ff more than Mesa model).
one process could proceed when a con- If the signaler checks for the condition,
dition becomes true. The broadcast we must ensure that the condition is not
primitive is also useful when a condi- invalidated between the time that the sig-
tion involves local variables because in nal occurs and the time that the blocked
this case the signaler cannot evaluate process actually executes. That is, we must
the condition (B above) for which a ensure that other execution in the monitor
process is waiting. Such a primitive is, does not interfere with the condition. If the
in fact, used in UNIX [Ritchie and signaler does not immediately relinquish
Thompson, 1974]. control of the monitor (e.g., if n o t i f y is
3.4.3 An Axiomatic View used), interference might be caused by the
process that established the condition in
The valid states of a resource protected by the first place. Also, if the signaled process
a monitor can be characterized by an asser- does not get reactivated before new calls of
monitor procedures are allowed, interfer-
17Of course, it is prudent to perform n o t i f y operations
only when there is reason to believe that the awakened
ence might be caused by some process that
process will actually be able to proceed; but the burden executes after the condition has been sig-
of checking the condition is on the waiting process. naled (this can happen in Modula [Wirth,
Computing Surveys, Vol. 15, No. 1, March 1983
Concepts and Notations for Concurrent Programming • 21
1977a]). Proof rules for monitors and the The manager construct [Silberschatz et al.,
various signaling disciplines are discussed 1977] for handling dynamic resource allo-
by Howard [1976a, 1976b]. cation problems and the scheduler monitor
[Schneider and Bernstein, 1978] for sched-
3.4.4 Nested Monitor Calls uling access to shared resources are both
based on this line of thought.
When structuring a system as a hierarchical The last approach to the nested monitor
collection of monitors, it is likely that mon- call problem, and probably t h e most rea-
itor procedures will be called from within sonable, is one that appreciates that moni-
other monitors. Such nested monitor calls tors are only a structuring tool for resources
have caused much discussion [Haddon, that are subject to concurrent access [An-
1977; Lister, 1977; Parnas, 1978; Wettstein, drews and McGraw, 1977; Paruas, 1978].
1978]. The controversy is over what (if any- Mutual exclusion of monitor procedures is
thing) should be done if a process having only one way tQ preserve the integrity of
made a nested monitor call is suspended in the permanent variables that make up a
another monitor. The mutual exclusion in resource. There are cases in which the op-
the last monitor called will be relinquished erations provided by a given monitor can
by the process, due to the semantics of be executed concurrently without adverse
w a i t and equivalent operations. However, effects, and even cases in which more than
mutual exclusion will not be relinquished one instance of the same monitor procedure
by processes in monitors from which nested can be executed in parallel (e.g., several
calls have been made. Processes that at- activations of a read procedure, in a moni-
tempt to invoke procedures in these moni- tor that encapsulates a database)~. Monitor
tors will become blocked. This has perform- procedures can be executed concurrently,
ance implications, since blockage will de- provided that they do not interfere w i t h
crease the amount of concurrency exhibited each other. Also, there are cases in which
by the system. the monitor invariant can be easily estab-
The nested monitor call problem can be lished before a nested monitor call is made,
approached in a number of ways. One ap- and so mutual exclusion for the monitor
proach is to prohibit nested monitor calls, can be released. Based on such reasoning,
as was done in SIMONE [Kaubisch et al., Andrews and McGraw [1977] defines a
1976], or or to prohibit nested calls to mon- monitorlike construct that allows the pro-
itors that are not lexically nested, as was grammer to specify that certain monitor
done in Modula [Wirth, 1977a]. A second procedures be executed concurrently and
approach is to release the mutual exclusion that mutual exclusion b e released for cer-
on all monitors along the call chain when a tain calls. The Mesa language [Mitchell et
nested call is made and that process be- al., 1979] also provides mechanisms that
comes blocked. TM This release-and-reac- give the programmer control over the gran-
quire approach would require that the mon- ularity of exclusion.
itor invariant be established before any
monitor call that will block the process.
3.4.5 Programming Notations Based
Since the designer cannot know a priori
on Monitors
whether a call will block a process, the
monitor invariant would have to be estab- Numerous programming languages have
lished before every call. A third approach been proposed and implemented that use
is the definition of special-purpose con- monitors for synchronizing access to shared
structs that can be used for particular sit- variables. Below, we very briefly discuss
uations in which nested calls often arise. two of the most important: Concurrent
PASCAL and Modula. These languages
~s Once signaled, t h e process will n e e d to reacquire have received widespread use, introduced
exclusive access to all m o n i t o r s along t h e call c h a i n novel constructs to handle machine-de-
before r e s u m i n g execution. However, if p e r m a n e n t pendent systems-programming issues, and
m o n i t o r variables were n o t p a s s e d as reference p a r a m -
eters in a n y of t h e calls, t h e process could reacquire inspired other language designs, such as
exclusive access incrementally, as it r e t u r n s to e a c h Mesa [Mitchell et al., 1979] and PASCAL-
monitor. Plus [Welsh and Bustard, 1979].
Computing Surveys, V~I. 16, NO; 1, March 1983
J : - .
. ...: .... . ..~:~:: ~.:: :~:i~ ,
22 • G. R. A n d r e w s a n d F. B. Schneider
3.4.5.1 Concurrent P A S C A L . Concur- vice modules, whicli a r e special interface
rent PASCAL [Brinch Hansen, 1975, 1977] modules for programming device drivers.
was the first programming language to sup- The run-time support system for Modula
port monitors. Consequently, it provided a is small and efficient. The kerne~ for a PDP-
vehicle for evaluating monitors as a system- 11/45 requires only 98 words of storage and
structuring device. The language has been is extremely fast [Wirth,1977c]. It does not
used to write several operating systems, time slice the processor among processes,
including Solo, a single-user operating sys- as Concurrent PASCAL does. Rather, cer-
tem [Brinch Hansen, 1976a, 1976b], Job tain kernel-supported operations--wait,
Stream, a batch operating system for pro- for example--always cause the processor to
cessing PASCAL programs, and a real-time be switched. (The programmer must be
process control system [Brinch Hansen, aware of this and design programs accord-
1977]. ingly.) This turnsout to be both a strength
One of the major goals of Concurrent and weakness of Modula. A small and effi-
PASCAL was to ensure that programs ex- cient kernel, where the programmer has
hibited reproducible behavior [Brinch Han- some control over processor switching, al-
sen, 1977]. Monitors ensured that patholog- lows Modula to be used for process control
ical interleavings of concurrently executed applications, as intended. Unfortunately, in
routines that shared data were no longer order to be able to construct such a kernel,
possible (the compiler generates code to some of the constructs in t h e language--
provide the necessary mutual exclusion). notably those concerning multiprogram-
Concurrent execution in other modules ruing--have asso'ciated restrictions that can
(called classes) was not possible, due to only be understood in terms of the kernel's
compile,time restrictions on the dissemi- implementation. A variety of subtle inter-
nation of class names and scope rules for actions between the Vari0us synchroniza-
class declarations. tion constructs must be understood in order
Concurrent PASCAL also succeeded in to program in Modula without experiencing
providing the programmer with a clean ab- unpleasant surprises. Some of these patho-
stract machine, thereby eliminating the logical interactions are described by Bern-
need for coding at the assembly language stein andEnsor [1981].
level. A systems programming language Modula implements an abstract machine
must have facilities to allow access to I/O that is well suited for dealing with inter-
devices and other hardware resources. In rupts and I/O devices on PDP-11 proces-
Concurrent PASCAL, I/O devices and the sors. Unlike Concurrent PASCAL, in which
like are viewed as monitors implemented the run-time kernel handles interrupts and
directly in hardware. To perform an I/O I/O, Modula leaves support for devices in
operation, the corresponding "monitor" is the programmer's domain. Thus new de-
called; the call returns when the I/O has vices can be added without modifying the
completed. Thus the Concurrent PASCAL kernel. An I/O device is considered to be a
run-time system implements synchronous process that is implemented in hardware. A
I/O and "abstracts out" the notion of an software process can start an I/O operation
interrupt. and then execute a doio statement (which
Various aspects of Concurrent PASCAL, is like a w a i t except that it delays the
including its approach to I/O, have been invoker until the kernel receives an inter-
analyzed by Loehr [1977], Silberschatz rupt from the corresponding device). Thus
[1977], and Keedy [1979]. interrupts are viewed as signal (send in
Modula) operations generated by the hard-
3.4.5.2 Modula. Modula was developed ware. Device modules are interface modules
for programming small, dedicated com- that control I/O devices. Each contains, in
puter systems, including process control ap- addition to some procedures, a device pro-
plications [Wirth, 1977a, I977b, 1977c, cess, which starts I/O operations and exe-
1977d]. The language is largely based on cutes doio statements to relinquish control
PASCAL and includes processes, interface of the processor (pending receipt of the
modules, which are like monitors, and de- corresponding I/O interrupt). The address
pability variables, which are variables hav- fiable systems. It has been used to imple-
ing fields whose values are the names of ment special-purpose systems for singie-
operations. A process can therefore have a and multiprocessor architectures.
changing set of communication channels. Distributed Processes (DP) [Brinch Han-
In SR, operations are specified by the in sen, 1978] was the first language to be based
statement, which also supports selective on remote procedure calls. It can be viewed
communications. Each guard in an in state- as a language that implements monitors by
ment has the form means of active processes rather than col-
lections of passive procedures. In DP, re-
op_.name(parameters) [and B] [by A]
mote procedures are specified as externally
where B is an optional Boolean expression callable procedures declared along with a
and A is an optional arithmetic expression. host process and shared variables. When a
The phrase " a n d B " allows selection of the remote procedure is called, a server process
operation to be dependent on the value of is created to execute the body of the pro-
B, which may contain references to param- cedure. The server processes created for
eters. The phrase " b y A " controls which different calls and the host process execute
invocation of o p _ _ n a m e is selected if more with mutual exclusion. The servers and
than one invocation is pending that satisfies host synchronize by means of a variant of
B. This can be used to express scheduling conditional critical regions. An extension of
constraints succinctly. For example, it per- D P that employs the rendezvous form of
mits a compact solution to the shortest-job- remote procedure call and thus has a more
next allocation problem discussed earlier. efficient implementation is described by
Although somewhat expensive to imple- Mao and Yeh [1980].
ment because it requires reevaluation of A StarMod [Cook, 1980] synthesizes as-
whenever a selection is made, this facility pects of Modula and Distributed Processes:
turns out to be less costly to use than it borrows modularization ideas from Mod-
explicitly programmed scheduling queues, ula and communication ideas from Distrib-
if the expected number of pending invoca- uted Processes. A module contains one or
tions is small (which is usually the case). more processes and, optionally, variables
Operations may also be declared to be shared by those processes. Synchronization
procedures. In SR, a procedure is short- within a module is provided by semaphores.
hand for a process that repeatedly executes Processes in different modules interact by
an in statement. Thus such operations are means of remote procedure call; StarMod
executed sequentially. provides both remote procedures and ren-
To support device control, SR provides dezvous for implementing the server side.
a variant of the resource called a real re- In StarMod, as in SR, both s e n d and call
source. A real resource is similar to a Mod- can be used to initiate communication, the
ula device module: it can contain device- choice being dictated by whether the in-
driver processes and it allows variables to voked operation returns values.
be bound to device-register addresses. Op- Argus [Liskov and Scheifler, 1982] also
erations in real resources can be bound to borrows ideas from Distributed Processes--
interrupt vector locations. A hardware in- remote procedures implemented by dynam-
terrupt is treated as a s e n d to such an ically created processes, which synchronize
operation; interrupts are processed by using critical regions--but goes much fur-
means of in statements. ther. It has extensive support for program-
ming atomic transactions. The language
4.5.5 Some Other Language Notations Based
on Message Passing
also includes exception handling and recov-
ery mechanisms, which are invoked if fail-
Gypsy [Good et al., 1979], one of the first ures occur during execution of atomic trans-
high-level languages based on message actions. Argus is higher level than the other
passing, uses mailbox naming and buffered languages surveyed here in the sense that
message passing. A major focus of Gypsy it attaches more semantics to remote call.
was the development of a programming A prototype implementation of Argus is
language well suited for constructing veri- nearing completion.
Semaphores
Critical Regions
PROCEDURE / MESSA GE
ORIENTED ~{ ORIENTED
Monitors Message Passing
Path Expressions
1980]; otherwise it can be implemented us- anisms is a bad idea. We, however, favor
ing message passing. Recent research has programming in the style appropriate to
shown that both message- and operation- the language.
oriented languages can be implemented
quite efficiently on distributed systems if 6. CONCLUSION
special software/fnTnware is used in the
implementation of the language's mecha- This paper has discussed two aspects of
nisms [Nelson, 1981; Spector, 1982]. concurrent programming: the key con-
In a recent paper, Lauer and Needham cepts--specification of processes and con-
argued that procedure-oriented and mes- trol of their interaction--and important
sage-oriented languages are equals in terms language notations. Early work on operat-
of expressive power, logical equivalence, ing systems led to the discovery of two
and performance [Lauer and Needham, types of synchronization: mutual exclusion
1979]. (They did not consider operation- and condition synchronization. This stim-
oriented languages, which have only re- ulated development of synchronization
cently come into existence.) Their thesis primitives, a number of which are described
was examined in depth by Reid [1980], who in this paper. The historical and conceptual
reached many conclusions that we share. relationships among these primitives are
At an abstract level, the three types of illustrated in Figure 9.
languages are interchangeable. One c a n The difficulty of designing concurrent
transform any program written using the programs that use busy-waiting and their
mechanisms found in languages of one class inefficiency led to the definition of sema-
into a program using the mechanisms of phores. Semaphores were then extended in
another class without affecting perform- two ways: (1) constructs were defined that
ance. However, the classes emphasize dif- enforced their structured use, resulting in
ferent styles of programmingNthe same critical regions, monitors, and path expres-
program written in languages of different sions; (2) "data" were added to the syn-
classes is often best structured in entirely chronization associated with semaphores,
different ways. Also, each class provides a resulting in message-passing primitives. Fi-
type of flexibility not present in the others. nally, the procedural interface of monitors
Program fragments that are easy to de- was combined with message passing, result-
scribe using the mechanisms of one can be ing in remote procedure call.
awkward to describe using the mechanisms Since the first concurrent programming
of another. One might argue (as do Lauer languages were defined only a decade ago,
and Needham) that such use of these mech- practical experience has increased our un-