Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.



Aync/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.


if 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.


You can find more info about how Haskell does it here: http://community.haskell.org/~simonmar/papers/multicore-ghc....


what language does "lightweight threads" exactly like this?


I 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.


Haskell for one, but lots of others: https://en.wikipedia.org/wiki/Green_threads


he 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!


The 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.


In a managed platform like .NET or Java there's no reason in principle why any code should be able to tell whether it's in an OS or a green thread - the decision of how to actually accomplish having multiple simultaneously active callstacks with pre-emptive scheduling is made by the runtime. Early versions of Java used green threads within the JVM rather than relying on native threads, presumably as part of an attempt to provide consistent write-once-run-anywhere behaviors, so this is not just theoretical.

I think the async/await model arrives as a reasonable compromise in terms of supporting an alternative to OS threads in that it allows you to get the benefits of green threads (i.e. that you can process a lot of different stack contexts simultaneously without needing to spin up a huge amount of OS threads) without getting into the messy situation of having a user-space scheduler pre-emptively switching green-thread stacks (which probably needs the scheduler itself to run on another OS thread and definitely needs to be done at a 'runtime' level) - instead, you just rely on co-operative scheduling, which can be done at a 'library' level.


> 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.


I can't imagine the fun you could get into in such a system where there are both green thread and OS thread locking primitives available...


Erlang?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: