5 ms·
It's also worth considering why .NET is conservative about spawning threads. The basic reason is that threads are really big objects. The default stack space al
by jameshart 10y ago
It's also worth considering why .NET is conservative about spawning threads. The basic reason is that threads are really big objects. The default stack space allocation for a 64bit thread in .NET is 4MB, so you do not want hundreds of these things getting spawned when your traffic spikes. Since most of your threads handling requests would be spending most of their time waiting for IO operations (network requests to DB servers being the most common wait state) to complete, this is a recipe for having huge blocks of committed memory sitting around, each holding a small amount of stack state for a single request (most of the request data being strings and dictionaries will be on the managed heap anyway, the stack will just contain a few references to those heap objects), waiting for a DB query to complete.
A web server using few threads and async/await state machines can transfer those stack states out into managed heap objects too, and handle many times more concurrent requests without running out of RAM.
- balfirevic 10y agoAync/await just seems like really heavy handed solution to this problem. I wish .Net runtime provided lightweight threads (with low memory and switching overhead) so that it would be possible to tune how application runs without needing to modify the code.
- platz 10y agowhat language does "lightweight threads" exactly like this?
- int_19h 10y agoErlang?
- balfirevic 10y agoI think JVM with Quasar gets close. It uses bytecode instrumentation to support suspending and resuming method execution. It modifies methods so that they know how to store and retrieve their stack state on heap when they are suspended and resumed. I think the Quasar API is not exactly what I described in my previous comment but the above building blocks are what is needed to achieve something close to it.
- porges 10y agoHaskell for one, but lots of others: https://en.wikipedia.org/wiki/Green_threads https://en.wikipedia.org/wiki/Green_threads
- platz 10y agohe added an additional requirement "to tune how application runs without needing to modify the code." So I assume that means not using things like forkio/goroutines etc.. You still have to tell haskell "fork a green thread here" instead of what he wants, which is it to be completely transparent. Additionally, I think one can make the case the haskell green threads aren't very different from async await, in which "awaiting" is just creating some data that a scheduler maps onto a threadpool (rather like how GHC maps it's 'green threads' onto it's 'capabilities' via a scheduler) Furthermore, if you actually want to pass data round in Haskell rather than just fork threads, it leaves it completely up to the user to figure out how to do that.. MVar's are canonical but noisy syntatically. the 'async' package is very nice, but gives the gives the same syntax OP is complaining about!
- balfirevic 10y agoThe transparency I'm after is that majority of your code can be oblivious to whether it's running in OS or green thread. So, for example, you could configure your web server to use use green threads to handle incoming http requests but configure other part of the system to run with real threads (for whatever reason). In the end, internally, it will of course end up similar to async/await - you need to capture the execution state and resume it which is what async/await does. I just want to be able to do it without rewriting majority of my code.
- platz 10y ago> configure your web server to use use green threads to handle incoming http requests but configure other part of the system to run with real threads this just seems like an odd feature imho, but sure i think i understand you better now.
- bbcbasic 10y agoif someone can chime in and say why .NET cannot have the lightweight threads like Haskell I would be interested. I am guessing because being pure/immutable there are no "stack frames" to store with the thread, just a reference to the (immutable) data passed in to a function.
- balfirevic 10y agoYou can find more info about how Haskell does it here: http://community.haskell.org/~simonmar/papers/multicore-ghc.pdf http://community.haskell.org/~simonmar/papers/multicore-ghc....