5 ms·
The problem, in my mind, is that many languages provide 'transparent' shared state between the threads - which can easily introduce very subtle bugs. The simpl
by smanek 17y ago
The problem, in my mind, is that many languages provide 'transparent' shared state between the threads - which can easily introduce very subtle bugs.
The simple solution is to requires any sharing of state to be made explicit (e.g., message passing). This obviously introduces some overhead, but I think it could eventually become like assembler v. higher level languages. A handful of very talented hackers will still be always be able to beat any threading abstraction by manually dealing with everything - but the abstractions will get more and more optimizations (e.g., copy-on-write variables, more static analysis) until you rarely bother looking underneath them.
- zokier 17y agoMay I ask you why the frack you are using threads if you don't want a shared state? You know what the difference between a thread and a process is right? Maybe you should learn to use your tools before bubblewrapping them for being dangerous. Look at how Google Chrome is made. Instead of using threads, they use processes for tabs. http://www.google.com/googlebooks/chrome/small_04.html http://www.google.com/googlebooks/chrome/small_04.html
- smanek 17y agoBecause if the language uses threads instead of processes the compiler can perform all sorts of neat optimizations on message passing. As a trivial example (an example I included in the post above yours), consider 'copy-on-write' optimizations. Thread A can pass a message containing Object O (which is 50MB) to Thread B. Naively, this would be pretty expensive - however the compiler can set things up so that a copy of O isn't made until either B or A tries to write to O (in which case in can even try to just copy the part that was mutated). This provides a healthy balance between the raw performance of fork-style threads and the safety of multiple processes. This sort of optimization wouldn't be possible just using processes since, obviously, Process B couldn't (or at least shouldn't ;-)) directly look into Process A's memory space. I never said don't share state - I just said don't transparently share state. Make it explicit and/or make it safe. As I said, it's never going to be quite as fast as raw fork-style threading but, with a sufficiently smart compiler, it can come close - and be a lot easier.
- pmjordan 17y agoActually, if you fork() a process, the memory pages of the new process are shared with the old, using copy-on-write access rules. Obviously, that doesn't enable any kind of communication, but can be damn handy if you need a read-only chunk of memory that is initialised once but needs to be shared with all processes involved.
- uriel 17y ago> The problem, in my mind, is that many languages provide 'transparent' shared state between the threads - which can easily introduce very subtle bugs. That is the reason languages like Limbo ( http://limbo.cat-v.org http://limbo.cat-v.org ) and Erlang were invented (and CSP, obviously).
- axod 17y agoAs I said "Programmers working on concurrency, locking, etc are often solving self inflicted problems." They're moot points IMHO. Trying to make languages that deal well with threads/concurrency is a pointless exercise. What's the advantage to doing this, over just not using threads?
- silentbicycle 17y agoEither that, or only use co-operative (not pre-emptive) multitasking via coroutines. Specifying the points at which control is allowed to switch from one to another is far easier than trying to reliably specify where it cannot and using locks. Message-passing works quite well, but coroutines are also a viable option. The problems come from using pre-emptive threads AND shared state, because reasoning about who is modifying what (and at what stage of completion) becomes difficult. Co-routines avoid the former, message passing the latter. Which is simpler overall depends on the problem.
- uriel 17y ago> Message-passing works quite well, but coroutines are also a viable option. Why not both as in CSP/Limbo? ;) Edit: Note that you can get both in C too using the confusingly named libthread(2) http://man.cat-v.org/plan_9/2/thread http://man.cat-v.org/plan_9/2/thread (Also available in Unix as part of Plan 9 from User Space http://plan9.us http://plan9.us )
- silentbicycle 17y agoYou can do either in Lua pretty easily, too. Doing both doesn't make much sense, though - schlepping around large data structures in message-passing can be a performance problem, but unlike coroutines, can be very easily switched to a run over multiple machines. Coroutines are in the core language, and there's also ConcurrentLua (http://concurrentlua.luaforge.net/ http://concurrentlua.luaforge.net/) for message passing.
- uriel 17y ago> schlepping around large data structures in message-passing can be a performance problem, Not really, it is not too hard to implement it locally as passing pointers around.