4 ms·
I've successfully replaced tokio with the lower-level mio in one such case. After all threads and async serve different purposes: Threads when you're computing
by mikojan 4y ago
I've successfully replaced tokio with the lower-level mio in one such case. After all threads and async serve different purposes: Threads when you're computing a lot, async when you're waiting a lot, no?
- deleted 4y ago[deleted]
- lumost 4y agoThreads work OK for concurrency in many apps. The developer cost of async may not be worth it in many cases.
- ibraheemdev 4y agoI would say that threads work _very well_ for concurrency in _most_ apps. Thread context switches have gotten much much cheaper over the years, and the idea that threads are heavyweight is very outdated.
- lumost 4y agoTrue, java apps have comfortably run 10s of thousands of threads without issue historically. Coroutines are nice as they allow trivially writing an app which scales to millions of concurrent operations. Rust is nice as it lets us write code for every occasion, async is awful as it poisons the entire ecosystem. The same result could have been achieved with a few tactically inserted yield statements for I/O and locking which are pretty much the only times that async or coroutines help.
- 411111111111111 4y agoI'm just an average web developer, so I could be wrong here, but that's not my understanding of it. Your application has n threads to begin with, if you use async, these will be utilized to schedule tasks. You're basically trusting your language to properly pause and restart the procedures. If you spawn new threads, these will be managed by your kernel. If that kernel is Linux, that it already has a pretty good algorithm to pause and restart them, so you're not really wasting a lot of resources. So I believe there are effectively two differences: threads can scale up to the limit of your os/kernel and hardware. Async can scale up to the level of the threads your language spawns to handle these tasks. Threads trust the kernel/OS to prioritize workloads, async trusts the language
- jhugo 4y agoThe important difference is in purpose, not implementation. Most async runtimes use a thread or more per core, and the OS is doing that thread scheduling, so it's not the either-or situation that you describe. The interesting thing about async (especially async-await) is that it is a fluent way to write a program that waits for events (e.g. I/O), without resorting to inefficient designs like thread-per-client in order to achieve concurrency. Software (even in C) has made use of this concept for a long time through poll() and friends; async-await is just a higher level abstraction over the same concept.
- 411111111111111 4y ago> The important difference is in purpose, not implementation. I couldn't disagree stronger on that one. Abstraction is generally good, but this becomes a purely philosophical discussion as soon as you ignore the actual implementation when talking about the differences of how something actuals behaves and should be used. And philosophical discussions like that have their place but are imo pointless in the context of what should be used, when. They're generally better placed in a context of deciding wherever you want to implement an abstraction I do fundamentally agree with the rest of your comment however. that's what I meant with trusting your language to prioritize workloads vs your OS.
- jhugo 4y agoI'm not saying that implementation doesn't matter. I'm saying that that there isn't a fundamental implementation difference "async" vs "threads". Threads are used in both cases. It's a different choice of abstractions over the same underlying concepts. FYI, Rust (the language) has no concept of prioritising workloads; there is no async runtime in the language. Even with any of the async runtimes, workloads (i.e. tasks doing work) are prioritised by the OS. It's just threads executing code. Async runtimes are primarily concerned with the gaps between work, like waiting for I/O or other events.
- FiberBundle 4y ago> If you spawn new threads, these will be managed by your kernel. If that kernel is Linux, that it already has a pretty good algorithm to pause and restart them, so you're not really wasting a lot of resources. Thread context switches are pretty expensive. If you use an async runtime such as tokio, all your tasks will be spawned on a fixed number of threads and you won't have any context switches on a task switch.
- paskozdilar 4y ago> After all threads and async serve different purposes: Threads when you're computing a lot, async when you're waiting a lot, no? It doesn't have to be one or the other. Go uses coroutines and multiplexes them onto multiple OS-level threads (usually as many as there are cores).
- mcronce 4y agoThat's what tokio does under the hood.