14 ms·
Why Threads are a Bad Idea (for most purposes) (1995) [pdf]
- EGreg 9y agoI agree. The actor model where actors can be scheduled on any thread is the best (Erlang, Goroutines). Second best is the node.js model of single threaded evented programming.
- ahoka 9y agoCan you back up your claims?
- EGreg 9y agoYes, but I can't be bothered to. How's that for an honest response lol.
- amelius 9y ago> The actor model where actors can be scheduled on any thread is the best (Erlang, Goroutines). Yes, but only if there can be structural sharing between threads.
- littlestymaar 9y agoThis presentation is not about Kernel thread versus green thread, it's about threads vs events. In this regards, Goroutines are as bad as threads since it requires some synchronization witchcraft (channel or locks) and the author advocates for your «second best one» (events).
- jerf 9y agoAt the time that this was written, "threading" encompassed the idea of threads sharing and mutating basically all of their state. In practice not every thread would touch everything, of course, but the concept model was that it was at least possible, and that it was the responsibility of data structures to be ready for concurrent mutation. While Go in theory is the same as a 1990s-style-threading model, and serious Go programmers had best not forget that in the final analysis they aren't actually protected from multithreading problems simply "because Go", having a model where structures are owned by particular threads, and things are shared via messages rather than direct threads, thus making it the thread's responsibility to be ready for incoming messages, makes it vastly, vastly easier to program in in practice. Yes, this absolutely could have been adapted back then, too. This once again goes back to the fact that a language is often more than just the language itself, but also includes the standard idioms and the standard and common libraries. You could have written your code in 1990s in the Go way in C++, but you would have had to bring up basically an entirely new library stack and written a lot of wrapping code around OS functionality. Despite the fact that Go programming is in practice much simpler than the threading being criticized in that paper, I agree strongly with the idea that Go would be enhanced by the ability to erect much stronger boundaries around goroutines to ensure that they neither share nor reach into anything they shouldn't. Still, there are ones by convention, which is way better than nothing. You should also consider Rust-style "synchronization witchcraft" as a very interesting alternative "isolated actors" and "locks everywhere" that strikes out in a new direction entirely. In 50 years what we currently consider all of our best sync options may in hindsight have proved to been simply a false dichotomy (albeit one with three or four choices rather than just 2, but, the same principle holds).
- EGreg 9y agoReplace data structures with actors and messages and you got it :)
- littlestymaar 9y ago> and things are shared via messages rather than direct threads, thus making it the thread's responsibility to be ready for incoming messages, makes it vastly, vastly easier to program in in practice. I kind of disagree, the Go mantra «don't communicate by sharing memory, share memory by communicating» is merely a marketing pitch, especially due to the clumsy nature of Go's channel[1]. Unfortunately, the number of Go developers being bitten by data races in Go is too high … The main danger here is the illusion of safety that the Go community is spreading (and your comment is an example of that): all the Go devs I know (including me) never really worked on multi-threaded C or C++ code before, and if you come from a nodejs or Python background like most do, you aren't really prepared to understand the challenges of multi-threaded programs. Sometimes the best way to structure your program is just to have a shared `map` of items you need to process, but if you forgot to wrap it in a mutex, you have a data-race. And if you don't even know what a data-race is, you face strange and unpredictable bugs (true story). [1] : http://www.jtolds.com/writing/2016/03/go-channels-are-bad-and-you-should-feel-bad/ http://www.jtolds.com/writing/2016/03/go-channels-are-bad-an...
- jerf 9y agoIf you have a public map that is being accessed by multiple goroutines, you've fought Go not once but twice; once for the multiple access, and once for it being public in the first place. At the very least make the map private and create an async-safe API around it. You definitely do have some responsibilities learning how to write truly multithreaded code after coming out of a single-threaded environment. However, having used quite a few environments, I don't know of any where that isn't true. You've fundamentally stepped up a level of complexity. In Haskell, you don't have to change too much about your style, excepting that you first had to write your code in Haskell, which most people consider quite a leap. In Erlang, you are forced to deal with process boundaries and there isn't really an equivalent of "just share a map"; even the obvious "just share a map" option (ets) is simply a prepared API around a process boundary. Rust's pretty cool, but you must write in accordance with its type system, and that's going to fundamentally change how you write programs if it's your foray into that sort of world, which is cool and good, but far more disruptive than learning how to write some Go. If Go makes a particular error here, it is that it doesn't stick the problems in your face and makes it a bit too easy. I'm actually on the side of that being a problem (if you think I'm all "rah rah" Go, go back and read the grandparent post with an eye for counterexamples, there's at least three), but I think most people coming from Python or Node would at least initially believe they prefer this. The reason I am a bit rah-rah on Go (just not unreservedly) is that while I still if I had my way would tweak some important aspects about it is that it's the first time it has brought that style of thinking (and libraries!) to the Algol-style languages. On the one hand, as a language dilettante I'm saddened that we lose some goodness from the non-Algol heritages, but on the other hand, it means I get to use it for my job without cringing. Haskell is... Haskell. Erlang's a neat language but it conflated a lot of stuff and forces a lot of adaptations on to you that I consider unnecessary. (I respect it and its developers deeply, but as is often the case the first effort in a certain space often makes errors that later generations will consider basic.) The C/C++/Java/C# space all pretty much went with 1990s-style threading. It's probably still the easiest entry into that space you can have, so I have a hard time laying too much blame at the language's feet rather than the problem domain's feet. (The channel criticisms are mostly legit, but at the same time, Go channels are probably better primitives than 80% of programmers have ever had access to. To see the complete picture one most manage to hold all of these aspects in one's head at once.)
- zzzcpan 9y agoEvent driven programming is actually very close to actor model conceptually, just slightly less powerful. And basically switching to actor model is the only path forward for someone coming from events. But yeah, people need to stop confusing actor model with shared-memory multithreading. Threads/green-thread/goroutines are all the same and the criticism applies to all of them. They share nothing with actor model (pun intended).
- notacoward 9y agoFew would disagree with "better" (than either pure threads or pure events) but if you're going to say "best" the burden of proof is higher. Please explain why you think actors are strictly better than e.g. promises/futures or agent-based models.
- EGreg 9y agoNo time to write it up.
- benjamin_mahler 9y agoKeep in mind that actors and futures can be used together, which produces an even more powerful result than either abstraction used alone. We use this programming model in Mesos via a library called libprocess. There will be some talks on this approach in upcoming MesosCons and we'll submit one to Cppcon.
- chrisseaton 9y agoIn terms of safety I think fork-join is better than the actor model. The actor model is all about mutable state - the state of all the actors. Fork-join removes state entirely - it's just about passing values.
- deleted 9y ago[deleted]
- mamcx 9y agoHow is the fork-join? How a program made in this model is better? I don't remember see any concrete example with that (I see CSP, Actor and Disruptor(?))
- chrisseaton 9y agoIn the actor model you can have non-determinism. Two actors are going to send you messages to update the state in a third. Depending on which message arrives first, you can arrive at a different final state in the third actor. And which can arrive first depends on scheduling issues that can change between runs. That's non-deterministic, and it's part of what makes multi-threading so hard. The fork-join model doesn't have this problem because you can only join a determinate number of tasks, and you have to join them in a determinate order. You can't have anything arriving at any other order than you specified. Scheduling issues cannot change how a fork-join program runs. In the actor model you also have a really complicated state situation. You've got n actors, all each in a possibly infinite number of states. Because of the non-determinism described above the states your actors will get into in each run of the program can be different. That's another part of what makes multi-threading so hard. The fork-join model doesn't have this problem because tasks don't have any state. They just have input and output. There's no state, only commutation. The actor model is a big uncontrolled graph of state in my opinion. Fork-join is DAG of pure functional computation done in parallel.
- mamcx 9y agoAny code example? In this model I think deadlocks is possible, like in CSP. I wonder if CSP is closer to this model, right?
- maxxxxx 9y agoHow do you handle long lasting operations like checking something from time to time? Seems to me this is a natural use for a thread.
- winstonewert 9y agoSchedule a timer, and respond to the timer events. Its a waste of resources to have a thread hanging around sleeping all the time.
- jdmichal 9y agoThis is basically "There is no Thread": https://blog.stephencleary.com/2013/11/there-is-no-thread.html https://blog.stephencleary.com/2013/11/there-is-no-thread.ht... There are times when you can offload an asynchronous task to non-CPU hardware, in which case the blocking thread can disappear. The thread reappears when the hardware asynchronously informs the CPU of task completion. (This idea is what Node.JS is entirely reliant upon.) Consider if we didn't have timing hardware to handle this task for us. We could implement a timer with a spin-loop thread which checks the clock and fires off events.
- pcwalton 9y agoGoroutines are just threads with a particularly idiosyncratic implementation.
- mjevans 9y agoEdit (first line); actually maybe it's my definition of 'thread' that is different. I think of a process as a security context that has one or more CPU routines (complete set of state). Goroutines are not threads in that sense, they lack that CPU state and are just segments of code (logic and data-state). Goroutines are 'soft threads'. The underlying implementation typically defaults to number of CPU cores as max possible REAL thread count. The real threads will check the message queues for possible wakeups when the previous soft thread blocks or terminates.
- computerex 9y agoThat's like saying chocolate cake is the best followed by blueberry muffins.
- Kenji 9y agoIt's the same with every tool: The more powerful it is, the worse the consequences are when it's abused. That applies to programming in particular.
- marcosdumay 9y agoWith great powers come great needs of formal verification.
- zzz95 9y agoNeed is there, but tools are not.
- Kenji 9y agoIt's not a tooling issue (see my comment above)
- deleted 9y ago[deleted]
- Kenji 9y agoFormal verification is pointless if there are no formal specifications of the program/product/whatever. And if there are formal specifications, then they might as well be in the form of code. And even formal specifications can contain errors. That is why verification is not more popular.
- notacoward 9y agoNote that it's from 1995. Back then, many people still thought that machines with multiple processors were exotic things of little interest even in the enterprise. That list most notably included one Linus Torvalds. It also included OP author John Osterhout, who should also have known better - even more so, since Stanford was one of the places where such things were not so exotic. He even says, right up front, that threads still have their uses when you need true CPU concurrency. Now that's a common case. Generalizing from this presentation to the current day is probably a worse idea than threads ever were.
- bbatha 9y agoClearly they never wrote for the butterfly[0] ;). [0] https://en.wikipedia.org/wiki/BBN_Butterfly https://en.wikipedia.org/wiki/BBN_Butterfly
- winstonewert 9y agoYour comment implies that the presentation says you shouldn't use thread. But that's not what it says. The conclusion is that you should only use threads when you are actually trying to achieve cpu concurrency.
- notacoward 9y ago"Only" In the context of that time, "only when you're trying to achieve CPU concurrency" was meant as "only if you're doing something exotic" (though it wasn't as exotic as Osterhout thought - I'd already been working on MP machines for years). In the context of this time, it means "only" in an extremely common case. The difference matters. People who read the presentation without putting it in historical context will be misled, even if Osterhout weasel-worded his conclusions because he kind of knew he was wrong already.
- greglindahl 9y agoToday, there are many places that have big clusters of multi-processor machines, and none of their code is threaded. They get cpu concurrency by message passing between heavy-weight processes and with other nodes.
- in9 9y agoLoved the programmer comparison slide. Is today's python programmer 1995's visual basic programmer? :D
- milesvp 9y agoYou've never worked with "wordpress programmers" have you?
- sethrin 9y agoIt's possible to be a "wordpress programmer" in any language, but man, I have read a lifetime's worth of bad PHP code. WordPress is of course the worst of all possible PHP worlds since it was a fork of an even more ancient project and thus had to maintain backwards compatibility with a purely procedural codebase. The phrase "wordpress programmer" conjures up the person for whom that is their sole form of programming expression. Some part of me acknowledges that people like that must exist: the rest recoils in horror.
- frozenport 9y ago"drupal programmer"
- bechampion 9y agoand still powers more than 25% of the interwebs... some claim.
- thesz 9y agoJohn Osterhout is a creator of Tcl, which embraces event-driven model for programming. I think it gives more perspective into his opinion. That said, Tcl was one of the first scripting languages which got very nice thread model - see AOLServer [1]. [1] https://en.wikipedia.org/wiki/AOLserver https://en.wikipedia.org/wiki/AOLserver We used Tcl threads in one of our programs to control various hardware things while main UI responded to events sent from the threads. Everything worked very well, especially for a program in scripting language like Tcl.
- woliveirajr 9y ago> Where threads needed, isolate usage in threaded application kernel: keep most of code single-threaded. This is the point where performance tops: each CPU is filled with operations, and operations that don't need to wait for the result of other threads.
- gens 9y agoObligatory CSP[0] reference. There are only a handful of examples, that i can think of, where threading(multiprocessing, concurrency, and other names for it) is useful. [0] http://www.usingcsp.com/ http://www.usingcsp.com/
- milesvp 9y agoTwenty years later this seems to still be good advice. Martin Thompson talks about this in his Mechanical Sympathy talk. He says the first thing he does, as a performance consultant, is turn off threading. Claims that's often all he needs to achieve the desired improvements... It's a good talk, I highly recommend it. https://www.infoq.com/presentations/mechanical-sympathy https://www.infoq.com/presentations/mechanical-sympathy
- ttoinou 9y agoWho creates threads just for fun ? I only use them when I really need them (in C++), so there's really no alternative for me
- YZF 9y agoYep. If all you have is a blocking sys call and you want performance you gotta have threads. If you want to use more than a single core at a time for computation, you gotta have threads. [And I use the word threads loosely, you could have multiple processes as well or whatever OS primitive let's you get concurrency]. A 20 core CPU can do some things 20 times faster than a single core (multiply matrices e.g.). If you're trying to do those things and you limit yourself to a single thread - good luck!
- skybrian 9y agoThe morning paper had a nice set of blog posts about this: Why they're equivalent (duals): https://blog.acolyer.org/2014/12/08/on-the-duality-of-operating-system-structures/ https://blog.acolyer.org/2014/12/08/on-the-duality-of-operat... Why threads are a bad idea: https://blog.acolyer.org/2014/12/09/why-threads-are-a-bad-idea/ https://blog.acolyer.org/2014/12/09/why-threads-are-a-bad-id... Why events are a bad idea: https://blog.acolyer.org/2014/12/10/why-events-are-a-bad-idea/ https://blog.acolyer.org/2014/12/10/why-events-are-a-bad-ide... Unifying events and threads (in Haskell): https://blog.acolyer.org/2014/12/11/a-language-based-approach-to-unifying-events-and-threads/ https://blog.acolyer.org/2014/12/11/a-language-based-approac... Unifying events and treads (in Scala): https://blog.acolyer.org/2014/12/12/scala-actors-unifying-thread-based-and-event-based-programming/ https://blog.acolyer.org/2014/12/12/scala-actors-unifying-th...
- i_feel_great 9y agoAnother great read on threads: The Problem with Threads, by Edward Lee: https://www2.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-1.pdf https://www2.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-....
- MichaelMoser123 9y agohe doesn't seem to have mentioned cooperative threads/green threads/non preemptive threads in this series http://wiki.c2.com/?CooperativeThreading http://wiki.c2.com/?CooperativeThreading They are easier to program than events, they still have problems like its easy to run out of a very limited stack and you have to yield your cooperative thread often to other tasks, but they are easier to maintain than a state machine (that is often done as a very big switch statement).
- Waterluvian 9y agoI'm using greenlets via gevent to handle a system that interacts with a number of http APIs, exposes an RPC API and has a data processing loop. I absolutely love the concurrency model. For cpu bound processes and short API timeouts, getting to control when my "threads" yield makes it very easy to avoid the common threading pitfalls. It also means my application can remain very simple. Ie. I don't need to think about things like Celery or Redis or handling locking meticulously.
- faragon 9y agoI can not agree more. Most people should not write threaded code at all.
- dreamdu5t 9y agoThreads are a bad idea for the same reason manual handling of memory space is a bad idea. Languages should provide primitives that only allow for safe construction of expressions that are run concurrently by the runtime.
- sqeaky 9y agoSo does that give people who write allocators license to to threads arbitrarily? More seriously, in C++ apps (Games financial trading etc...) it is common enough to need to carefully manage memory to get that last bit of performance even after saturating all the CPUs and GPUs. Superficially your advice makes sense. Going forward I think I might leave threads in the same mental bucket as allocators and see if that heuristic holds up.
- pyre 9y ago> Languages should provide primitives that only allow for safe construction of expressions that are run concurrently by the runtime. Then you run into issues like that post recently where you can't have different threads running in different context, because the runtime is the one deciding/controlling when new threads are spawned.
- vyodaiken 9y agoThe key point is unstructured shared data is a source of errors in a threaded program.
- ythn 9y agoWhat if I have a blocking function call (i.e. listening on a socket)? Seems like there is no choice but to put the blocking call in its own thread...
- rini17 9y agoAll modern operating systems support event interface to sockets (like select, epoll). And OP actually says that limiting usage of threads to handle blocking stuff is fine.
- littlestymaar 9y agoWhy should you use a blocking mecanism for listening on a socket ? Non-blocking I/Os[1] (epoll on Linux) have been a thing for a long time now. [1] : https://en.wikipedia.org/wiki/Asynchronous_I/O https://en.wikipedia.org/wiki/Asynchronous_I/O
- kbwt 9y agoExcept when the non-blocking file I/O API[1] is actually a blocking one. Yes, I realize in this case it's the API that needs fixing, but it isn't looking like that will happen anytime soon. [1] : https://lwn.net/Articles/723752/#724198 https://lwn.net/Articles/723752/#724198
- zzzeek 9y agoThe answer from anti threading proponents would say you should never use blocking IO.
- sbov 9y agoI'm sure many people don't think this applies to them because they don't use threads. However, in the modern day, replace "thread" with "process" and "memory" with "database", and many web applications have very similar problems. They just never actually manifest because of the small number of requests per second.
- gnaritas 9y agoNo, the problems of threads don't carry over to processes, what you just said is exactly wrong and misunderstands the issues involved. Databases have transactions and processes don't share memory, those solve the problem with threading which is shared non transactional memory.
- zzzeek 9y agoTransactions lock and conflict with each other, so the metaphor holds fairly closely though not completely equivalent of course
- gnaritas 9y agoYes but these are recoverable states whereas threads suffer from partial reads in the middle of updates resulting in undefined unpredictable behavior. It's not a good metaphor to compare threads to processes as they suffer from vastly different failure modes and problems and are quite normally contrasted to each other as different solutions to concurrency problems.
- zzzeek 9y agothe reason people don't want to use threads is because they're afraid of having to understand race conditions. At that level, "you will have to understand race conditions no matter what" is the wisdom I derive from this particular metaphor.
- atemerev 9y agoYes, might have worked in 1995. Now, however, when even your lowly phone has 4 (or more) processor cores and a full-fledged GPU... Learn concurrent programming techniques — or perish. Threads and sync primitives are low-level, but important, and you have to understand them to figure out what compromises and biases were taken in higher-level models. And, frankly, it isn't that bad (debugging existing code is bad, but playing with monitors and semaphores and critical sections is easy, until code is small and isolated).
- kbutler 9y agoYes, and no. Concurrency and parallelism are important, but threads (lightweight shared memory processes) are not the only solution. Successful, popular concurrent platforms like Erlang/OTP, Nginx, and node.js, eschew threads in favor a single-threaded, async/non-blocking code model. These platforms simplify application-level code by avoiding the issues of thread synchronization and contention in a shared memory space, and instead provide/require isolated processes to exploit CPU-level parallelism. The threading "isn't that bad" viewpoint generally comes from a limited understanding of the things that can go wrong - for instance, add "memory barriers" to the list of things to understand. There's a good explanation of the problems with a common Java idiom "double-checked locking" at https://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html https://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedL... Of course, when things get complicated with lots of interactions between processes, or significant amounts of computation in a single-threaded process, some platforms require the user to manually yield, etc., basically trying to re-create preemptive threading provided by the OS.
- dragonwriter 9y ago> Successful, popular concurrent platforms like Erlang/OTP, Nginx, and node.js, eschew threads in favor a single-threaded, async/non-blocking code model. Erlang, the language, is threading model agnostic, but the main implementation has been, by default, M:N threaded on systems with multiple logical processors since, AFAICT, the R12B release in 2008. So characterizing it as single threaded is inaccurate.
- outworlder 9y agoFrom a Linux perspective, threads and processes are essentially the same construct. The major difference is the set of flags that are passed when the process is created. Oversimplifying, if shared memory is requested, then it's a thread. Otherwise, it's a process. Meaning forking servers are multi-threaded. On other operating systems, specifically those starting with the letter W, there's a major distinction. There are other constructs as well, such as "fibers". Now, today's world is different from what it was in 1995. We used to have a single core, so threads and multiple processes were only a logical construct. Now, we have multiple cores, so we shold, at a bare minimum spawn multiple processes/threads. What's running inside them can then be debated as if it were 1995.
- joosters 9y agoIMO, the main problem with using threads is that they are such an 'all or nothing' approach to sharing data. If you want to make use of multiprocessing, the traditional choice is either to use two separate processes (sharing nothing), or to use threads (and share everything). But for most tasks, these opposite ends of the spectrum are not what you need. There's plenty of data and state in most programs that doesn't need to be shared, and a huge source of threading bugs is through mistakenly altering some data that another thread was using. The problem is that sharing partial state between processes is painful and many languages and OSs make it difficult to do. You have to play around with mmap() or other shared memory tools, and then pay great attention to not mix pointers or other incompatible data between the processes.
- cjensen 9y agoIf I had a dollar for every time I heard "thread programming is hard." I've programmed using threads for 23 years. I've never had a non-trivial debug issue caused by trouble using semaphores, mutexes, and shared data. It's no harder than writing a hash table or balancing a tree.
- julian_1 9y agoDo you have proofs for your code that it can't deadlock or livelock? How strong are your claims - would you trust it in a life support system, or aircraft auto-pilot, or similar role?
- cjensen 9y agoNope. Nor do I have any proofs that my balanced binary tree implementation is correct, or that my hash implementation is correct. Given the number of stories about equator issues and negative altitude issues in autopilots, I'm unconvinced there are proofs involved in those either.
- julian_1 9y agoI would trust my own multi-threaded code too, but it requires much stronger knowledge of expected behaviors and code paths. I have had the misfortune to try and debug other's multithreaded code. Having a debugger connected to a production app, while waiting a week for it to deadlock is tedious.
- YZF 9y agoIt's easier when you restrict yourself to: - take mutex - read/write/modify shared data structure - release mutex There are plenty of multi-threaded RTOS and a lot of critical embedded software is multi-threaded. Typically there are clearer guarantees in those vs e.g. Linux. Multi-threaded code isn't fundamentally (from a theoretical perspective) different than single threaded code when it's running on a single core. Multiple cores communicating is sort of orthogonal.
- oconnor663 9y ago
- ilaksh 9y agoThreads have been useful for me in my latest experiment. Its a C++ application that runs mame_libretro dll (copies) each in their own thread, while a BASIC intepreter runs in another thread, and the main game engine (Irrlicht) runs in the main thread. Irrlicht isn't multithreaded so I just put commands from the BASIC thread into an outgoing deque which I lock and unlock as I access it. Then there are mutexes for the video data. I think that threads are definitely a bit tricky though since it is easy to mess up locking/unlocking or not lock things necessary and if you do then you have debugging headaches. So when not needed they should be avoided I think.
- dgreensp 9y agoI'd rather have real threads available in my language, and use shared state sparingly. Your N single-threaded processes have to talk to each other anyway, or at least to a master, and might even share memory through memory-mapping. Threads are just a tool, and they give you options. You can use them in a share-nothing way if you want. As someone who grew up on the Java VM and started my start-up/web career on it, I've always felt like Java programmers have a different relationship with threads than C programmers. Java gives you cross-platform, usable, debuggable native threads; it basically makes them free if you want them. In C/C++, on the other hand, threads are a library, and using them is a grungy affair. If you grew up on Rails, meanwhile, threads don't exist ("when you say worker thread, do you mean worker process? I'm confused"). Node.js was created by C programmers and launched with a lot of anti-thread propaganda, much like the link. They equated threads with shared state, and also said threads were too memory inefficient to be practical for a high-performance server (they meant that holding a native thread for every open connection would require too much stack space, which is true, but that's not what they said).
- valarauca1 9y ago>As someone who grew up on the Java VM and started my start-up/web career on it, I've always felt like Java programmers have a different relationship with threads than C programmers. Java gives you cross-platform, usable, debuggable native threads; it basically makes them free if you want them. In C/C++, on the other hand, threads are a library, and using them is a grungy affair. The difference is Java threads work within the constraints of the JVM memory model. Which is very well specified and understood. It is implemented in the JVM and the JVM guarantees your platform will follow it. While C/C++ do what ever the hardware dictates. https://dzone.com/articles/java-memory-model-programer%E2%80%99s https://dzone.com/articles/java-memory-model-programer%E2%80...
- dgreensp 9y agoThat's part of it, for sure.
- kulu2002 9y agoWhatever... But Multithreaded systems are fun to design, develop and most importantly - troubleshoot... more harder the 'real time'ness more the fun :)
- Animats 9y agoThe bad idea is taking a threaded language and retrofitting events, which Python is doing. This results in an even worse mess. Python now has two kinds of blocking, one for threads and one for events. If an async event blocks on a thread lock, the program stalls. Or taking a event-driven language and retrofitting concurrency, which Javascript is doing. That results in something that looks like intercommunicating processes with message passing. That's fine, but has scaling problems, because there's so much per-process state. Languages which started with support for both threads and events, such as Go, do this better. If a goroutine, which is mostly an event construct, blocks on a mutex, the underlying thread gets redispatched. There's only one kind of blocking.
- srean 9y agoAlmost no one likes Tcl, but I think it used(uses) a nice model for concurrency. Much better than Python's. Interpreter as a library, all state encapsulated in a reentrant interpreter object, different interpreters running in different threads that can send messages to each other, no need for expensive serialization deserialization (like in Python) because the interpreters are in the same process, ... so much nicer.
- geezerjay 9y agoThere's a link to a related discussion on HN entitled "Why Events Are a Bad Idea (for high-concurrency servers) (2003)" https://news.ycombinator.com/item?id=14548487 https://news.ycombinator.com/item?id=14548487