3 ms·
What would be "just working" in your mind WRT promise, unwrap and thread context semantics? Sugar around thread yield, unwrap and context return? That seems l
by jayd16 5y ago
What would be "just working" in your mind WRT promise, unwrap and thread context semantics?
Sugar around thread yield, unwrap and context return? That seems like a lot of possible gotchas to simply be hidden and lurking under every benign looking synchronous method.
Remember that the point of async/await is cooperative threading and not pre-emption. Hiding these details makes it much harder to reason about. If you don't know when your execution will be yielded, you're essentially being pre-empted, no?
- gpderetta 5y agoSure, you can be preempted by another thread (or even process) even within an async function, so why should it matter? The borrow checker should still prevent anything bad from happening. I'm not a rust programmer, but personally I think that stackless coroutines are probably a necessary evil in system languages as full stack switching might have too much overhead. But let's stop pretending that it is actually a good thing. Still I think that even with stackless coroutines await should be the default (the async keyword would be used if you explicitly want the promise), which, in addition to better ergonomics, would allow the async-ness of a function to be inferred, possibly as a function of its type parameters. This at the very least would avoid duplicating a lot of functionality.
- jayd16 5y ago>Sure, you can be preempted by another thread (or even process) even within an async function, so why should it matter? You misunderstand. Its not about whether your thread can be pre-empted, its that your logical execution can hold exclusive access to a thread. There are common design patterns that use exclusive threads as a means of synchronization.
- gpderetta 5y agoI understand. What I'm saying is that marking async points explicitly is neither necessary nor sufficient to guarantee exclusive use of the thread. The borrow checker or some other explicit critical section markers are a better soluiton.
- roblabla 5y ago> Sure, you can be preempted by another thread (or even process) even within an async function That really depends on the platform. Async rust is also being leveraged to build RTOS on embedded platform for instance. If async rust was preemptive by default, that would be impossible. It's not a matter of performance there, but of correctness.
- Matthias247 5y agoIt would actually be very hard to build a RTOS using async functions - and the current use of async/await on embedded Rust is indeed not about RTOS, it's just embedded code. The reason for that is that the point of a RTOS is providing guarantees: A certain task should be guaranteed to run within a certain time. To provide that guarantees, the RTOS needs to support preemption and prioritization. That allows it to schedule a certain task even if another task is running for too long. I'm not aware about any RTOS which makes use of cooperative multitasking.
- jlokier 5y ago> I think that stackless coroutines are probably a necessary evil in system languages as full stack switching might have too much overhead. I think it's worth noting that the big operating system kernels - perhaps the ultimate target of "system languages" - tend to use stackful coroutines rather than stackless. Stack switching tends to be similar speed overhead than stackless, despite surface appearances in how the code may appear. Stackless tends to do more memory allocation and freeing, though.
- gpderetta 5y agoSure, but the perceived advantage of stackless coroutines is not faster switching time, but lower peak memory usage. OSs do not run 100s of thousands of tasks as threads, and when they do they use hand written state machines.
- jerf 5y agoGreen threads, like Go has, is one good answer. You don't run around annotating what is and is not async. It just works. Even full OS threads are an acceptable answer for the vast majority of applications. It is good and proper for embedded programmers and OS designers and such to have options as powerful as Rust, but that does not mean the average program written in Rust is embedded, an OS, or needs to be able to scale to hundreds of thousands of threads. (I actually think reaching straight for async/await is a mistake, personally. It's a tool for more extreme situations, not something you reach for when you're writing a program that's going to intermittently consume a fraction of a percent of CPU, or run a quick job where it may need maybe 10 threads if that and terminate. A lot of people badly overestimate the resources they need and jump straight for the extra-mega power tools for problems where they are literally a dozen orders of various magnitudes (CPU, RAM, etc.) away from needing them for their task.) (It is extra ironic to be terrified of threads when working in a language like Rust that has so thoroughly tamed them!) Yes, there are compromises, so you get the flip side of what I said above: Just because something has costs doesn't mean it doesn't have benefits. It is a benefit that you don't have to annotate everything yourself and the compiler and runtime just takes care of it. "Remember that the point of async/await is cooperative threading and not pre-emption." I disagree. Cooperative threading is a disaster. It doesn't scale. We tried it, very very hard, with an entire major consumer OS for decades. The point of async/await is precisely to get something like pre-emption into something that isn't using full, real threads (as its primary organization). That it functions like cooperative threading is one of the disadvantages that happens to be an acceptable compromise at most scales, not a goal.
- jayd16 5y ago>Cooperative threading is a disaster. It doesn't scale It doesn't need to scale because it solves a different problem. It find extreme success in UI and graphics programming where UI systems are dominated by a single UI thread for synchronization. GPU have been single threaded until recently. You can argue you do not like it but I can't see how you can argue against it's success. That said, I'm pretty interested to see a popular multithreaded/pre-emptive UI framework in the wild.