Rob Pike gave a talk at Google about the NewSqueak programming language, and specifically how it's concurrency features work. NewSqueak uses channels and is based on the concepts of Communicating Sequential Processes.
The <channel> word creates a channel that threads can send data to and receive data from. The 'to' word sends data to a channel. It is a synchronous send and blocks waiting for a receiver if there is none. The 'from' word receives data from a channel. It will block if there is no sender.
There can be multiple senders waiting, and if a thread then receives on the channel, a random sender will be released to send its data. There can also be multiple receivers blocking. A random one is selected to receive the data when a sender becomes available.
I'm not sure if I've got the best stack effect ordering for the words but it gives something to experiment with and work out the best interface. I've not yet done a 'select' or 'mux' words.
Here is the 'counter' example ported from NewSqueak:
: (counter) ( channel n -- ) [ swap to ] 2keep 1+ (counter) ; : counter ( channel -- ) 2 (counter) ; : counter-test ( -- n1 n2 n3 ) <channel> [ counter ] spawn drop [ from ] keep [ from ] keep from ;
Given a channel, the 'counter' word will send numbers to it, incrementing them by one, starting from two. 'counter-test' creates a channel, spawns a process to run 'counter', and then receives a few values from the channel.