How channels work
Indirect communication using channels (''e.g.'' Gilles Kahn and David MacQueenSynchronous channels
Synchronous channels have the property that a sender putting a message in the channel must wait for a receiver to get the message out of the channel before the sender can proceed.Simple synchronous channels
A synchronous channel can be modeled by an Actor that receivesput
and get
communications. The following is the behavior of an Actor for a simple synchronous channel:
*Each put
communication has a message and an address to which an acknowledgment is sent when the message is received by a get
communication from the channel in FIFO order.
*Each get
communication has an address to which the received message is sent.
Synchronous channels in process calculi
However, simple synchronous channels do not suffice for process calculi such asput
and get
messages; however at most one of the guards can be chosen for each execution of the guarded choice command. Because only one guard can be chosen, a guarded choice command in general effectively requires a kind of X
, Y
, and Z
. The repetitive guarded command in the definition of Z
has two alternatives:
#the stop
message is accepted from X
, in which case Y
is sent the value false and print
is sent the value n
#a go
message is accepted from Y
, in which case n
is incremented and Y
is sent the value true.
If Z
ever accepts the stop
message from X
, then X
terminates. Accepting the stop
causes Y
to be sent false which when input as the value of its guard will cause Y
to terminate. When both X
and Y
have terminated, Z
terminates because it no longer has live processes providing input.
In the above program, there are synchronous channels from X
to Z
, Y
to Z
, and Z
to Y
.
Analogy with the committee coordination problem
According to KnabeA simple distributed protocol
This section presents a simple distributed protocol for channels in synchronous process calculi. The protocol has some problems that are addressed in the sections below. The behavior of a guarded choice command is as follows: *The command sends a message to each of its guards toprepare
.
*When it receives the first response from one of its guards that it is prepared, then it sends a message to that guard to prepare to commit
and sends messages to all of the other guards to abort
.
**When it receives a message from the guard that it is prepared to commit
, then it sends the guard a commit
message. However, if the guard throws an exception that it cannot prepare to commit
, then guarded choice command starts the whole process all over again.
*If all of its guards respond that they cannot prepare
, then the guarded command does nothing.
The behavior of a guard is as follows:
*When a message to prepare
is received, then the guard sends a prepare
message to each of the channels with which it is offering to communicate. If the guard has booleans such that it cannot prepare
or if any of the channels respond that they cannot prepare
, then it sends abort
messages to the other channels and then responds that it cannot prepare
.
**When a message to prepare to commit
is received, then the guard sends a prepare to commit
message to each of the channels. If any of the channels respond that they cannot prepare to commit
, then it sends abort
messages to the other channels and then throws an exception that it cannot prepare to commit
.
**When a message to commit
is received, then the guard sends a commit
message to each of the channels.
**When a message to abort
is received, then the guard sends an abort
message to each of the channels.
The behavior of a channel is as follows:
*When a prepare to put
communication is received, then respond that it is prepared if there is a prepare to get
communication pending unless a terminate
communication has been received, in which case throw an exception that it cannot prepare to put
.
*When a prepare to get
communication is received, then respond that it is prepared if there is a prepare to put
communication pending unless a terminate
communication has been received, in which case throw an exception that it cannot prepare to get
.
**When a prepare to commit to put
communication is received, then respond that it is prepared if there is a prepare to commit to get
communication pending unless a terminate
communication has been received, in which case throw an exception that it cannot prepare to commit to put
.
**When a prepare to commit to get
communication is received, then respond that it is prepared if there is a prepare to commit to put
communication pending unless a terminate
communication has been received, in which case throw an exception that it cannot prepare to commit to get
.
***When a commit put
communication is received, then depending on which of the following is received:
****When a commit get
communication is received, then if not already done perform the put
and get
and clean up the preparations.
****When an abort get
communication is received, then cancel the preparations
***When a commit get
communication is received, then depending on which of the following is received:
****When a commit put
communication is received, then if not already done perform the get
and put
and clean up the preparations.
****When an abort put
communication is received, then cancel the preparations.
***When an abort put
communication is received, then cancel the preparations.
***When an abort get
communication is received, then cancel the preparations.
Starvation on getting from multiple channels
Again consider the program written in CSP (discussed in Synchronous channels in process calculi above): , Y :: guard: boolean; guard := true; * ">, Z :: n: integer; n:= 0; * Y?go()_ → _n_:=_n+1;_Y!true">?stop()_ → _Y!false;_print!n; __________[Y?go()_ → _n_:=_n+1;_Y!true_.html"_;"title="/a>Y?go()_ → _n_:=_n+1;_Y!true">?stop()_ → _Y!false;_print!n; __________[Y?go()_ → _n_:=_n+1;_Y!true_">/a>Y?go()_ → _n_:=_n+1;_Y!true">?stop()_ → _Y!false;_print!n; __________[Y?go()_ → _n_:=_n+1;_Y!true_ As_pointed_out_in_Knabe_Z
_might_never_accept_the_stop
_message_from_X
_(a_phenomenon_called_Resource_starvation.html" "title="/a>Y?go()_ → _n_:=_n+1;_Y!true_.html" ;"title="/a>Y?go() → n := n+1; Y!true">?stop() → Y!false; print!n;
[Y?go() → n := n+1; Y!true ">/a>Y?go() → n := n+1; Y!true">?stop() → Y!false; print!n;
[Y?go() → n := n+1; Y!true
As pointed out in Knabe Z
might never accept the stop
message from X
(a phenomenon called Resource starvation">starvation
Starvation is a severe deficiency in caloric energy intake, below the level needed to maintain an organism's life. It is the most extreme form of malnutrition. In humans, prolonged starvation can cause permanent organ damage and eventually, dea ..."start"
is received, then send Z the message "stop"
*the Actor Y is created with the following behavior:
**If the message "start"
is received, then send Z the message "go"
**If the message true is received, then send Z the message "go"
**If the message false is received, then do nothing
*the Actor Z is created with the following behavior that has a count n
that is initially 0:
**If the message "start"
is received, then do nothing.
**If the message "stop"
is received, then send Y the message false and send print the message the count n
.
**If the message "go"
is received, then send Y the message true and process the next message received with count n
being n+1
.
By the laws of Actor semantics, the above Actor system will always halt when the Actors X, Y, are Z are each sent a "start"
message resulting in sending print a number that can be unbounded large.
The difference between the CSP program and the Actor system is that the Actor Z does not get messages using a guarded choice command from multiple channels. Instead it processes messages in arrival ordering, and by the laws for Actor systems, the stop
message is guaranteed to arrive.
Livelock on getting from multiple channels
Consider the following program written in CSP oare 1978 [Bidder1 :: b: bid; *[Bids1?b → process1!b; [] Bids2?b → process1!b;] , , Bidder2 :: b: bid; *[Bids1?b → process2!b; [] Bids2?b → process2!b;] ] As pointed out in KnabeBidder2
might never accept a bid from Bid1
or Bid2
(a phenomenon called process2
might never be sent anything. In each attempt to accept a message, Bidder2
is thwarted because the bid that was offered by Bids1
or Bids2
is snatched away by Bidder1
because it turns out that Bidder1
has much faster access than Bidder2
to Bids1
and Bids2
. Consequently, Bidder1
can accept a bid, process it and accept another bid before Bidder2
can commit to accepting a bid.
Efficiency
As pointed out in KnabeSummary of Issues
The subsections above have articulated the following three issues concerned with the use of synchronous channels for process calculi: #''Starvation.'' The use of synchronous channels can cause starvation when a process attempts to get messages from multiple channels in a guarded choice command. #''Livelock.'' The use of synchronous channels can cause a process to be caught in livelock when it attempts to get messages from multiple channels in a guarded choice command. #''Efficiency.'' The use of synchronous channels can require a large number of communications in order to get messages from multiple channels in a guarded choice command. It is notable that in all of the above, issues arise from the use of a guarded choice command to get messages from multiple channels.Asynchronous channels
Asynchronous channels have the property that a sender putting a message in the channel need not wait for a receiver to get the message out of the channel.Simple asynchronous channels
An asynchronous channel can be modeled by an Actor that receivesput
and get
communications. The following is the behavior of an Actor for a simple asynchronous channel:
*Each put
communication has a message and an address to which an acknowledgment is sent immediately (without waiting for the message to be gotten by a get
communication).
*Each get
communication has an address to which the gotten message is sent.
Asynchronous channels in process calculi
The Join-calculus programming language (published in 1996) implemented local and distributed concurrent computations. It incorporated asynchronous channels as well as a kind of synchronous channel that is used for procedure calls. Agha's Aπ Actor calculus is based on a typed version of the asynchronousAlgebras
The use of algebraic techniques was pioneered in the process calculi. Subsequently, several different process calculi intended to provide algebraic reasoning about Actor systems have been developed in , , .Denotational semantics
Will Clinger (building on the work of Irene GreifReferences
*Carl Hewitt, Peter Bishop and Richard Steiger. A Universal Modular Actor Formalism for Artificial Intelligence IJCAI 1973. *Robin Milner. Processes: A Mathematical Model of Computing Agents in Logic Colloquium 1973. *Irene Greif and Carl Hewitt. '