- Shiva Poudel
In this article, we will discuss how CSP and actor concurrency models work.
Communicating Sequential Processes (CSP)
Communicating Sequential Processes (CSP) is a model put forth by Tony Hoare in 1978 which describes interactions between concurrent processes. It made a breakthrough in Computer Science, especially in the field of concurrency.
In CSP we use "channels" for communication and synchronization. Although there is decoupling between the processes, they are still coupled to the channel.
It is fully synchronous, a channel writer must block until a channel reader reads. The advantage of that blocking based mechanism is that a channel only needs to ever hold one message. It's also in many ways easier to reason about.
Actor model was put forth by Carl Hewitt in 1973 and it adopts the philosophy that everything is an actor. This is similar to the everything is an object philosophy used by some object-oriented programming languages.
It is inherently asynchronous, a message sender will not block whether the reader is ready to pull from the mailbox or not, instead the message goes into a queue usually called a "mailbox". Which is convenient, but it's a bit harder to reason about and mailboxes potentially have to hold a lot of messages.
Each process has a single mailbox, messages are put into the receiver's mailbox by the sender, and fetched by the receiver.
Some differences between the actor model and communicating sequential processes:
- Processes in CSP are anonymous, while actors have identities.
- CSP uses channels for message passing, whereas actors use mailboxes.
- Actor must only communicate through message delivery, hence making them stateless.
- CSP messages are delivered in the order they were sent.
- The actor model was designed for distributed programs, so it can scale across several machines.
- Actor model is more decoupled than CSP.
I think both are fantastic concurrency models and are quite underrated. I'm not sure why everyone just went with the multi-threading hype and forgot about these models given they were here since the 1970s.
It is great to see languages like Go, Rust, Scala, and Elixir bringing these powerful concepts back into the discussion. Personally, I find these models much more natural than multi-threading, STM, Guilds, etc.
Do you think one is better than the other? I'd love to hear your thoughts.