-3

I'm giving a talk on concurrency which will cover multithreading, multiprocessing and green threads. I'd like to give simple real-world analogies of single threaded programs, multithreading, multiprocessing, and green threads. These are the analogies I've come up with:

  1. Single kernel thread - A single line of customers in a bank queuing up and being served by a single bank teller.
  2. Kernel multithreading - A single line of customers being served by two bank tellers.
  3. Multiprocessing - Two lines of customers being served by two bank tellers. (Or alternatively, two separate banks, each with a single line of customers being served by a single teller.)
  4. Green threads - A receptionist who is taking large numbers of calls and placing people on hold while they deal with other calls.

I don't really like the green threads analogy because (1) the people on hold are "blocking" rather than doing useful work; and (2) it is not consistent with the other bank teller analogies.

Anyone have any simple analogies that can help to explain green threads?

aco
  • 101
  • 2
  • see [Why do 'some examples' and 'list of things' questions get closed?](https://softwareengineering.meta.stackexchange.com/a/7538/31260) – gnat Mar 03 '19 at 07:12
  • 1
    I'm not asking for a list of examples, though. I'm asking for an analogy that demonstrates a computer science topic. IMHO it's no more subjective than asking for a piece of code that demonstrates a computer science topic. – aco Mar 04 '19 at 09:08

3 Answers3

3

It doesn't really make sense to include green threads in the same list as the other three, since they live on different levels of abstraction. Multithreading and multiprocessing are two different models of dealing with data sharing between concurrent entities (shared memory vs. separate memory with explicit communication).

Green threads on the other hand, are a way of implementing multithreading. One of many possible ways, actually.

If multithreading is implemented inside the CPU, we call it chip multithreading (CMT) if it is coarse-grained (e.g. on the T-series family of SPARC CPUs), and simultaneous multithreading (SMT) if it is fine-grained (e.g. on the Intel Xeon and Pentium4, under Intel's marketing name "HyperThreading Technology"). If it is implemented inside the Operating System, we call it Kernel Threading. If it is implemented at a higher level, we call it Green Threading. But it is all just different implementations of the same idea.

Jörg W Mittag
  • 101,921
  • 24
  • 218
  • 318
  • The terminology could be improved (I would probably use the word "fiber" instead of "green thread"), but when speaking about generalized pros & cons it does make sense to bring up all three. For the average user, the difference between multi-threading inside the kernel vs inside the chip (as well as the various combinations thereof) is likely to be academic. "Broad stroke" fiber/thread/process differences are likely to be more informative, as they involve larger architecture differences. – aerohammer Mar 03 '19 at 08:34
  • Yes, fair enough. I will rephrase the question as "kernel multithreading". – aco Mar 03 '19 at 09:39
  • 1
    @aco: But again, kernel multithreading and green multithreading are the exact same thing from a programmer's perspective (unless you are the one writing the language implementation of course), just implemented at a different place. For example, when Rubinius switched from green threads to kernel threads, there was exactly *nothing* that programmers needed to change in their programs, and *nothing* changed in the behavior of their programs. – Jörg W Mittag Mar 03 '19 at 10:31
  • 1
    Green threads and kernel multithreading are quite different from the programmer's perspective. Green threads use cooperative multitasking, so the program needs to explicitly yield control, unlike kernel multithreading which uses preemptive multitasking. Also, because green threads don't run in parallel, you often don't need to worry about locking resources, etc. – aco Mar 04 '19 at 09:02
  • @aco: What makes you say that green threads are cooperative? For example, early versions of the Sun JVM had preemptive green threads. Also, what makes you say that green threads don't run in parallel? They do in the BEAM/HiPE VM, for example, and they were designed that way (although never implemented) in Rubinius. OTOH, CPython uses kernel threads, but it doesn't run them in parallel. – Jörg W Mittag Mar 04 '19 at 09:48
  • I can't see how green threads could achieve parallelism without cooperation from the kernel, but maybe we have different definitions of green threads. I am talking about green threads in the sense of greenlet/gevent/asyncio/twisted/etc. I'm not familiar with Erlang/BEAM, but from what I can see, it doesn't actually implement green threads (e.g. see https://stackoverflow.com/a/1947210/2113516). The lack of parallelism in CPython has nothing to do with kernel threads; it's a userland implementation detail. – aco Mar 04 '19 at 10:05
  • @aco: if BEAM processes did share their memory, they would be "true" green threads and still be just as parallel as they are today. Green threads are simply threads that are implemented inside the runtime engine instead of in the OS. But, for example, since every Erlang data structure is serializable, and Erlang threads/processes are Erlang data structures, you can serialize them and send them to another VM running on a different OS thread (or even a different computer). – Jörg W Mittag Mar 05 '19 at 22:14
  • Rubinius's green threads worked the same way, they were implemented as serializable Ruby data structures, and were supposed to achieve parallelism by being scheduled to and from VM instances running on different OS threads. It's just that this scheduler was never implemented, and they then switched over to OS threads. – Jörg W Mittag Mar 05 '19 at 22:15
  • @JörgWMittag - In order for BEAM processes to share their memory and run in parallel, they would need to be implemented in the kernel. – aco Mar 06 '19 at 23:14
  • @aco no, you just need an OS that allows multiple *processes*. And that includes "physically separate hardware". The memory is not shared, data is passed through normal inter-process channels – Caleth Mar 07 '19 at 09:19
  • @Caleth - That is multiprocessing, which is not the same thing as green threads. – aco Mar 07 '19 at 23:20
  • @aco: There is no reason that BEAM "threads" couldn't be implemented the same way they are today, except sharing a single garbage collected heap instead of having one GC per process as they do now. That's what Rubinius wanted to do and (partially) implemented. – Jörg W Mittag Mar 09 '19 at 14:03
  • @JörgWMittag - They would not be parallel if there were implemented purely in userland (i.e. green threads). – aco Mar 17 '19 at 00:52
  • @aco: Today, BEAM green processes are implemented purely in userland, and they *are* parallel. They are, in fact, even distributed; you can ship one off to a different machine, which is precisely possible *because* they are implemented in userland. Since parallel is just a special case of distributed, they are then also trivially parallel. People quickly figured out that since green processes are distributed, they could simply run 4 VMs on their 4-core machine and assign 4 IP addresses to them. If we tried to do the same with green threads, it would be a little harder to make them distributed – Jörg W Mittag Mar 17 '19 at 01:06
  • … since we would need a network-transparent distributed shared mutable heap, but it's not impossible, And keeping them parallel is easy, we know how to share memory on a single machine, every OS has facilities for that. And I repeat again, Rubinius's threads were implemented fully in userland, and (if the implementation had been finished before it was replaced) would have been parallel precisely *because* they were implemented 100% in userland. If they had been in the kernel, they wouldn't have been Ruby objects, therefore, they wouldn't have been serializable, therefore, it wouldn't have … – Jörg W Mittag Mar 17 '19 at 01:09
  • … been possible to send a thread to a different VM to run it over there, therefore, they wouldn't have been parallel. It was precisely the fact that they were pure Ruby objects that made them parallel. – Jörg W Mittag Mar 17 '19 at 01:10
  • @JörgWMittag - BEAM processes use the fork() system call, i.e. they call kernel code. It's not possible to implement processes in purely userland code. – aco Mar 17 '19 at 09:11
0

Green threads would be a bank teller filing a transaction, then telling the customer to go back to the end of the line because someone on another floor needs to approve a particular part before they can continue.

This would probably work better if it involved paperwork that could be either carried around by the "tellers" (user threads & processes) or the "customers" (green threads). Banking doesn't work well with this unless you're assuming a very busy loan department.

aerohammer
  • 334
  • 1
  • 6
  • 1
    What you are describing sounds more like a data dependency, and is independent of whether you use green threads, kernel threads, multiprocessing, actors, goroutines, or any other concurrency model. – Jörg W Mittag Mar 03 '19 at 08:22
  • Yeah, unfortunately I can't immediately think of a better description using the bank teller model, hence the second paragraph. Bank tellers just don't work well for this if you want to add in green threads. – aerohammer Mar 03 '19 at 08:28
  • Thanks - I agree with @JörgWMittag but this gives me some ideas. By the way, it doesn't necessarily need to be a bank teller analogy, if you can think of a consistent theme of analogies for the other topics. – aco Mar 03 '19 at 09:55
0

Since it's fine to use a different style of examples, and it's that time of year in America, lets use taxes! Note that I left the old response, since this one is rather different...

A Green Thread is like doing your personal taxes and your business taxes yourself... as a mad scientist. You fill in the paperwork, schedule the time spent from what you have available to you, delay things because you need to go get more records, resume work that you left unfinished the day before, etc. All by yourself, except that you don't notice, because each time you change what you're doing, you pull out your brain and stick a different one in, thereby forgetting what you were doing until you swap that brain back in. Let Igor's brain handle the baking, you'll handle the eating!

A single Platform thread , whether an OS thread, a hardware thread, or more commonly a hardware thread used by the OS to implement an OS thread, does work differently. As far as you can tell, you just keep working on something thing until you decide not to. However, you don't have to decide to switch to something else as often, because the Platform (Doctor Frankenstein!) will sometimes do that for you (the Monster!), swapping your current brain with another (often Igor! But sometimes Bob from next door) without telling you. Stuff that needs fast reactions (Igor, the cake is burning!) is usually expected to get first dibs whenever this happens. Note that you can chose to run a Green Thread within a Platform Thread, but it's pretty hard to think of a scenario where it CAN'T be claimed that all Green Threads run inside one or more Process Threads. Regardless, the "special unicorn magic" is that you are no longer making the decision to swap brains threads.

Two or more Platform Threads is like a single Platform Thread, except that there now appear to be two+ bodies, thus two+ brains, so you can choose to have different brains do different jobs (Two Igors mean twice as many cakes)!

Multi-processing is when there are multiple sets of brains, and the body(-ies) get moved around to different places by one (or more) of the brains, so that brains in one set never wind up in places that are restricted to another set of brains (the Villagers will never know!).

aerohammer
  • 334
  • 1
  • 6