5 ms·
If you have 1:1 threads in a language, can't you implement M:N threading as a library? Looking at projects like Akka[1] makes me think this is the case. Is th
by eeperson 13y ago
If you have 1:1 threads in a language, can't you implement M:N threading as a library? Looking at projects like Akka[1] makes me think this is the case. Is there reason this can't be done that I am missing? Why would you want M:N threads baked in to the runtime?
[1] http://akka.io/ http://akka.io/
- arielweisberg 13y agoThose are usually leaky abstractions that don't allow you to do blocking operations with the idiomatic APIs and libraries of the language. You have to use the wrappers provided by the threading library which are typically incomplete and prevent you from using standard tools.
- brassybadger 13y agoI have no experience with Akka, but what you write makes sense. Even Clojure concurrency primitives feel weird sometimes when one wants to mix them with low-level Java libraries. Another option is to do it at the language level - see my comment on Erlang.
- eeperson 13y agoAren't blocking operations also a problem if M:N threads are baked in to the runtime? If all of the idomatic APIs are using non-blocking IO then would there still be a problem?
- arielweisberg 13y agoWhen M:N threads are truly baked in (either at the runtime level or the OS) blocking an M thread doesn't block the underlying N thread. An example would be Erlang which is a runtime built from the ground up to support lightweight threads where reading or writing to a socket of using the built in APIs won't block the underlying OS thread. You can still sabotage the runtime by writing your own native library and doing blocking operations from there, but the pitfalls are more obvious in that scenario. If the underlying concurrency and network/disk IO primitives are truly non-blocking for lightweight threads then everything built on top of them will also be non-blocking. Non-blocking for the underlying OS thread that is. That is where co-routines and other co-routine like libraries are a leaky abstraction. If you step into one of those blocking APIs in a third party or standard library you will block the underlying OS thread. This means you can't integrate with existing code or tools easily and you are always vulnerable to accidentally doing so.
- eeperson 13y agoHow do run blocking code in a way that doesn't block an OS thread? Is there some abstraction that allows this that I'm missing?
- Qerub 13y agoYou let the blocking call do a non-blocking call internally and then instruct an IO-aware user-mode scheduler to reschedule the user-mode thread when the non-blocking call has a result. This is what Haskell/GHC, Erlang and Ruby 1.8 do. There are some great papers on GHC's IO manager. In general, it is always possible to build a blocking interface on top of a non-blocking.
- eeperson 13y agoI guess I wasn't clear in my previous question. I know you can build a blocking interface our of a non-blocking one. My question was how you go the other way. How do you create a non-blocking interface of of a blocking one. The parent post seemed to imply that Erlang was able to do this. As far as I can tell this can't actually be done. If you have a blocking call you still have to block an OS thread somewhere. If this can't be done, then that brings me back to my previous point. It seems like the important thing is that you have non-blocking IO and not that you have an M:N threading model in the runtime. If you have non-blocking IO then it seems like you could easily implement an M:N threading model as a library without making it awkward to interact with. Is there some assumption I'm making that doesn't make sense?
- Qerub 13y agoThe Erlang runtime uses non-blocking IO calls to the kernel but exposes blocking functions on top of this. Is such a function really blocking? It depends on what level you're looking at; it's blocking at Erlang level but non-blocking at kernel level. I think this is the source of the confusion. You are of course correct in saying "If you have a blocking call you still have to block an OS thread somewhere." if you're looking at kernel level, but not Erlang level (since it can translate blocking to non-blocking). > If you have non-blocking IO then it seems like you could easily implement an M:N threading model as a library without making it awkward to interact with. Yes, but your language/system has to have some mechanism to manage control flow. Examples: F# does what you ask for via asynchronous workflows. Ruby via fibers/EM-Synchrony. Java via a bytecode weaver like Kilim.