proj-plbook-plChMessagePassing

Table of Contents for Programming Languages: a survey

Chapter: message passing

message passing

pipe

socket

and channel... ?

pub/sub

signals

actor

Example of selective receive in Ada's "rendezvous-based" concurrency: In Ada, "it allows you to treat a thread as an object with methods; calling a method on the object sends a message to the thread.", eg:

    loop
      select
        when usage < capacity =>
          accept Push(value: in integer) do
            data[usage] := value;
            usage := usage + 1;
          end;
      or
        when usage > 0 =>
          accept Pop(value: out integer) do
            usage := usage - 1;
            value := data[usage];
          end;
      or
        terminate;
      end select;
    end loop;

[1]

channels

synchrononus (unbuffered) and async (buffered)

In Golang, closing a closed channel panics (therefore, close is not idempotent). A send to or a receive from a nil channel blocks forever, a send to a closed channel panics, and a receive from a closed channel returns zero [2]. In combination with Golang's select statement, this can lead to useful idioms [3].

The Golang feature proposal [4] opines that this works okay when you have 1 sender and N receivers on a channel but that it's not great for having multiple senders on the channel. It suggests providing an operation to attempt to send to a channel that doesn't panic when the channel is closed, and suggests reference-counting both receivers and senders (separately) of each channel channels and auto-closing them when they have no senders or no receivers. Replies by a Golang designer [5] [6] like the reference counting idea but are skeptical of having close by receivers function as a signal to senders, for reasons i don't fully understand. In the special case of buffered channels, one reason is that items that the sender has already sent, that are sitting in the buffer when the channel is closed, may never arrive.

Golang's 'select' only works on channels and needs the programmer to know how many inputs it is selecting between in advance (unlike epoll) (i think Golang provides 'reflect.Select' for when you don't know how many things you have to select on?). Some have proposed that 'select' should work on any custom synchronization primitive, such as condition variables [7].

Some have proposed a way to make arbitrarily buffered channels (buffered channels with no fixed buffer size limit) in order to make channels that don't block [8]. Another (? is this distinct from all of the above suggestions?) suggestion is to allowing the 'dup' syscall to apply to channels, and then allowing someone to 'close' the dup'd channel without affecting the original one [9].

alternative: callbacks

Links: