I am in the design phase of a programming language, currently thinking about the concurrency aspects. I need to figure out a consistency model, i.e. how data is handled by concurrent processes programmed in this language.
There are two important criteria:
- I prefer ease-of-use over performance, as long as the consistency model allows good scaling,
- I cannot use a consistency model that requires blocking or dynamic memory allocation.
My two candidates right now are non-blocking software transactional memory on one side, and copying message-passing semantics without sharing a la Erlang.
I'm particularly worried about ease-of-use, so I'll present the major arguments I have against each of these two models.
In the case of STM, the user must understand what members of a class must mutate atomically and correctly delimit atomic code sections. These must be written so that they can be repeated an undefined number of times, they may not perform any I/O, may not call some foreign functions, etc. I see this as far from easy for a non-experienced programmer.
Erlang-style share-nothing concurrency is attractive, but there is a catch: real-time processes cannot copy the objects they send over, because they cannot perform any memory allocation, and so objects have to "move" from one process to the other via queues. The user must be aware that if one real-time process has two references to an object, both those references will be cleared if he sends the object to another process. This is a little like weak pointers that may or may not be null at any point of use: it may be surprising.
I tend towards the second model because it appears easier to understand and it naturally extends to distributed systems.
What do you recommend?
- Non-blocking software transactional memory?
- Erlang-style concurrency with the difficulties of real-time constraints?
- Something else I haven't considered?