People always used to ask me for advice on multithreading, because I had a reputation for multithreaded code that worked. I recommended they use Retlang (there's a Java version called Jetlang), which works on a shared-nothing message passing basis (and is blindingly fast). They tended to say they didn't want a library and just wanted to use locks and threads. I said that not doing that was how come I had a reputation for correctness.
When Steve Jobs was away due to his illness, Bertrand Serlet presented Mac OS 10.6 (Snow Leopard) at the WWDC June 2009 with the startling slide that said "0 new features". There was sustained applause from the crowd. But in fact there was a very significant under-the-hood new feature called "Grand Central Dispatch". It is a low-level API that removes a lot of the pain of multithreading. Essential for OS X and iOS developers, as it turns out.
In my 30+ years experience of concurrency, the shared-nothing message model makes it relative easy to reason about concurrency (since every actor is single threaded).
I have worked with Java, C# and Python, and for each I have developed a concurrent object framework, making it quite easy to work with multible channels of incoming events, for example for process control systems with barcode-scanners, scales, I/O-busses etc. connected to the system
I think ponylang does a pretty good implementation of the Actor model.
Feel free to have a look at the Python impl. of the framework (www.github.com/pylots/pyworks)
I'm surprised nobody's mentioned Clojure in the comments. Its concurrency abilities are top-notch, straightforward to use, and immutable data makes it dead-simple to avoid issues.
In the distant past, I did low-level multithreaded programming in the patchwork style of synchronizing access to various data. Partly because the codebase already did it that way and partly because i didn’t know better. These days I would never torture myself with such a thing. I still do concurrency sans framework, but like in the article - lock free with no sharing. Copying a block of data when it’s ready is cheap compared to computing it.
Hey, if you're curious about anything else I wrote in that blog post, just ask me. I thought the concurrency was a big highlight, but there's lots of other parts of D that I would love to talk about.
As I said, the whole thing was very enjoyable. I had lots of fun using D.
I like concurrency in Rakudo Perl 6. (https://docs.perl6.org/language/concurrency)
Especially the .hyper method that turns a regular sequence into hyper sequence that gets processed in parallel. First 5000 prime numbers:
# single-thread, takes 14.893s put ^∞ .grep(*.is-prime).head: 5000 # multi-threaded, takes 8.853s on my 2-core box put ^∞ .hyper.grep(*.is-prime).head: 5000
BeOS had an threading implementation like this in C++ in 1999: https://www.haiku-os.org/legacy-docs/bebook/TheKernelKit_Thr...
For a C++ implementation of actor patterns, see: https://www.actor-framework.org/
A shout out to the GPars framework  which makes actor based coding stunningly easy in Groovy / Java. I'm kind of shocked by the performance I can get out of it, to be honest. I once assumed that for trivial tasks (reading lines from a file, transforming them, writing out result etc), a parallel library would lose a lot of overhead in thread synchronisation. However I find that I can trivially construct data flows that massively outperform single threaded C code in Groovy. Which is to say, whatever overhead there is from thread synchronisation is dwarfed by the benefit of parallelising reading, computation and writing. If I had to think hard about concurrency to do it (as I would in C) I would probably never attempt it for simple programs, but GPars makes it so easy, safe and completely portable that there's really no reason not to.
On the other hand an Actor modelled implementation can - will - quickly get out of hand if you start using it to directly represent a business domain. Actor signature is Any -> Unit which essentially means “computes anything” plus there’s internal state (become), message queue size, problems with deterministic testability and so on.. I think Actors as an alternative to Threads, particularly valuable for its distributed supervisor trees, and used to build more abstract consumers for a strongly typed model of business representations.
It amazes me to no end that CML-style concurrency is not used more often. (Even though Go is sort of almost there)
I have been using guile fibers for some time, and it is a marvel! Not only can I write most code as if it was single threaded, but I can mix fibers code with pthreads and use fibers message passing when I need it.
If anyone is looking for another language that also uses the actor model for concurrency and has very similar ways of handling it like D, then checkout Erlang. It's language lessons are clearly still relevant today. :)
I don't see what's so good with that. Don't we have multiprocessing and threading pools that does that stuff automatically ?
Obligatory, but Haskell, comment.
Nice post, looks like a decent API. I wonder how similar each implementation of this model in Language X is and how easily it would be to test their implementation meet the spec.
tl;dr Guy discovers message passing and actors.
I'm not a professional programmer, but I had no problems with Java's multithreading libraries. Lock handling, synchronization etc are a pain in the ass to get used to but not so much of a big deal, and I don't see how D is any different than that.