5 ms·
> they don't have that many advantages anyway even in languages where they do work. Are you sure about that? One of the main advantages of coroutines/greenlets
by tomp 11y ago
> they don't have that many advantages anyway even in languages where they do work.
Are you sure about that? One of the main advantages of coroutines/greenlets IMO is writing simple and straightforward blocking code (e.g. an echo server); without them, you either need to use threads (which are slower and much more heavyweight) orcallbacks or related constructs (async/await, futures, ...).
- pcwalton 11y agoThreads aren't that slow on Linux. The main advantage of M:N threading as implemented in Go over 1:1 is that spawning is fast and doesn't use much memory, because you can avoid the syscall and only a small (initial) stack is required. Rust can't do the latter because it's not GC'd. Even if it could, many real-world servers actually do non-trivial work in their threads, so the cost of spawning a thread is dwarfed by the actual work the thread ends up doing. There are serious drawbacks to M:N: complexity, fairness, problems in interoperability with the 1:1 world (including essentially unavoidable performance problems with the FFI), etc.
- agentS 11y agoFor servers that primarily speak RPC or HTTP, do you foresee Rust going thread-per-request or something more callback-y?
- eddyb 11y agoNeither. Existing successful solutions use tight event loops (the "Reactor pattern": https://stackoverflow.com/questions/3436808/how-does-nginx-handle-http-requests https://stackoverflow.com/questions/3436808/how-does-nginx-h...). There is a Rust library called "mio" which provides a lot of the plumbing for such systems: https://github.com/carllerche/mio https://github.com/carllerche/mio. The path forward is likely going to involve adding a way to build cheap state machines (call them generators or async/await) with a clean syntax and giving mio hundreds of thousands of reusable instances.
- agentS 11y ago> ... Reactor pattern ... I don't understand, and the link seems unclear. Perhaps a more direct question: I get a request X, and I need to consult a backend service to answer the request. Do I write synchronous code calling that backend? Or do I have some callback mechanism? > ... generators or async/await Ah. This perhaps answers my question. Both of these are essentially compiler-written callbacks. If this is going to be like C#, then I presume there will be a thread-pool where user code will execute. It seems like a non-ideal story for concurrency. Users will have to take inordinate care not to call any blocking code; otherwise they will prevent one of the threads in the pool from doing useful work.
- pcwalton 11y ago> It seems like a non-ideal story for concurrency. Users will have to take inordinate care not to call any blocking code; otherwise they will prevent one of the threads in the pool from doing useful work. The downsides of going M:N are worse. The cgo-like FFI performance problems, for example, are killer for Rust's use case.
- pcwalton 11y agoMost applications right now should do thread-per-request. Thread spawning is very optimized in both Rust and the Linux kernel, and you can adjust stack sizes if you need to. If you're hitting limits caused by this, you can use mio.