I was trying to ask this question in StackOverflow, but later realized that this question is more relevant to general computer science, not specific engineering problems. If you think it's not, please let me know.

Recently I've found out what CSP(Communicating Sequential Processes) is.

According to the article Bell Labs and CSP Threads:

Most computer science undergraduates are forced to read Andrew Birrell's “An Introduction to Programming with Threads.” The SRC threads model is the one used by most thread packages currently available. The problem with all of these is that they are too low-level. Unlike the communication primitive provided by Hoare, the primitives in the SRC-style threading module must be combined with other techniques, usually shared memory, in order to be used effectively...

Another article Share memory by communicating from Golang blog says:

Traditional threading models (commonly used when writing Java, C++, and Python programs, for example) require the programmer to communicate between threads using shared memory (...)

Go's concurrency primitives - goroutines and channels - provide an elegant and distinct means of structuring concurrent software. (These concepts have an interesting history that begins with C. A. R. Hoare's Communicating Sequential Processes.)

Based on what I've seen so far, because Hoare proposed CSP in 1978, it seems that there was no reason to use SRC thread model in programming languages ​​like C++(1985), Java(1995) or Python(1990).

So my question is, why the most dominant programming languages didn't follow Hoare's thread model?

Here's my guesses:

  1. Most programmers back then didn't know about Hoare's thread model.
  2. Most programmers are used to traditional thread model.

What do you think?


Practically speaking, the C++ threading (memory) model is directly inspired by the Java Memory Model, and C followed. Hans Böhm was closely involved with the process and has a great resource list. (*)

You'll quickly note that your dates are pretty optimistic - this memory model did not exist in 1985 when the first C++ implementations were created. There's a practical reason for this. Even in 2000, it wasn't clear which model of parallel computing was going to win. Parallel extensions to mainstream languages were first defined as ad-hoc extensions by the hardware vendors, and later partially standardized by such things as POSIX threads and MPI.

Because of the challenges involved, you see that parallelism support is added first to languages used in high-performance computing. Even C++ was a bit late to the party; C and FORTRAN were the main languages. Java, by virtue of being late, had a chance to learn lessons from those. And since it was designed as a portable language, Java needed a clean memory model not tied to a particular hardware vendor's implementation.

So the common memory model can be traced to various actual hardware implementations that could be unified by a single definition. And this led to a secondary effect: because this was now a standard, software started to use it, and hardware vendors generally followed suit.

There's another winner in the parallelism space: GPGPU's. They entered the competition via a different way. NVidia's CUDA is a similar vendor-extension to C, C++ and FORTRAN. This was possible because the GPU market justified independent development, and the general-purpose use of GPU's was a lucky coincidence.

* This development can be dated pretty accurately, the use of the Java memory model for C++ was presented at the 2001-10 ISO C++ meeting in Redmond, WA.

  • 1
    $\begingroup$ This answer seems to be focused on "memory models", which are a formal set of guarantees. However people were writing threaded code and thread libraries and languages with supports for threads long before there was a memory model for it. So, I doubt that this answers the question the original poster was wondering about. The SRC thread library/model long predates the Java memory model, and the C++ memory model (and C's, too? does C have a memory model?). $\endgroup$ – D.W. Jan 20 '20 at 18:21
  • 1
    $\begingroup$ In an ideal model, we'd first construct a memory model before designing a programming language, but that's not how things worked in the early days. $\endgroup$ – D.W. Jan 20 '20 at 18:21
  • $\begingroup$ It seems that which technology is adopted is determined by practical reasons, rather than apparent advantages. Then do you think which model of parallel computing is clear now? $\endgroup$ – Tura Jan 21 '20 at 2:18
  • $\begingroup$ @D.W.: ISO C indeed has a thread/memory model; it's the same as C++ and Java. While C and C++ have a divergent evolution, on such fundamental topics there's collaboration between their respective committees to keep a base level of interoperability. $\endgroup$ – MSalters Jan 21 '20 at 10:10
  • 1
    $\begingroup$ @Tura, I don't know what you're asking. I doubt that the comments are the place to discuss it. I'm not sure I'd use the word "parallel computing" for what threads give you, exactly. Yup, my experience is that technology adoption is influenced by practical reasons. $\endgroup$ – D.W. Jan 21 '20 at 17:06

There are many approaches for concurrency, with different tradeoffs. We have threads with shared mutable state (e.g., SRC-style threading). We have coroutines (like Go). We have actor models with independent processes communicating via message passing (like Erlang or E).

I would put CSP on a different level. It's not the same sort of thing. The form of CSP that I am familiar with is a mathematical, theoretical formalism that can be used to model concurrent systems. It's not really a model of programming that can be directly used in programming languages. It's more like the lambda calculus. You can build programming language APIs inspired by CSP, just like Lisp and Scheme are inspired by the lambda calculus, but it's not directly a design of a thread API itself.

Why did early languages choose to follow the SRC model rather than something inspired by CSP? Well, all I can share with you is speculation. The SRC model is a low-level model that maps pretty closely to the primitives provided by processors: it is a thin level of abstraction over that. Just like C is a thin layer over assembly language (and doesn't use, say, functional or declarative paradigms), it's not surprising that early languages would provide a thin layer over processor primitives (rather than, say, other theoretical paradigms). Also, the SRC model works well with existing code and existing programming languages. You can take existing sequential code and then add threads. When you're writing threaded code, the sequential part of the computation looks just like code written for a non-threaded language. That backwards compatibility and familiarity was probably significant. The SRC model could be deployed as a library, without requiring changes to programming language syntax or compilers. I have to imagine that might have been a significant factor in its adoption. Also, the SRC model is somewhat similar in many ways to existing Unix primitives for running code in parallel in multiple processes, which I imagine might also have been beneficial for adoption. This is just my speculation. Perhaps someone else will be able to provide a more researched answer.

  • $\begingroup$ +1 for clarifying the position of CSP with respect to other concepts. To summarize your answer, SCR model is more low-level friendly and compatible with existing ecosystem - that is important factor of adoption, right? $\endgroup$ – Tura Jan 21 '20 at 0:58
  • $\begingroup$ @Tura, yes, that's my impression -- or at least, it was at the time. $\endgroup$ – D.W. Jan 21 '20 at 1:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.