3 ms·
Async/await can easily be implemented through channels. I view channel as providing superset of functionality then async/await at least. Granted there are other
by YetAnotherNick 6y ago
Async/await can easily be implemented through channels. I view channel as providing superset of functionality then async/await at least. Granted there are other paradigms like lock free synchronization which can not be directly be translated to channel.
- pjmlp 6y agoSo how do you change the scheduling algorithm though channels?
- YetAnotherNick 6y agoasync/await and channel are independent of scheduling. Nodejs doesn't have multithread but has async/await. I find goroutines lightweight enough in my personal testing and didn't tried tweaking it.
- pjmlp 6y agoOn .NET and C++ they surely are not, given that you can fine tune them either by providing new schedulers, magic methods on awaitable objects that can be either value or reference types. So not only you can control the scheduling algorithm, you can control how the async/await state gets managed in memory and also introduce additional parameters that influence the decision when to switch tasks across owner threads. Try to do this in Go via channels, while offering just the channel syntax to the caller. EDIT: The only thing in common between JavaScript, Python, .NET, C++ and Kotlin async/await is the name of the primitives.
- unscaled 6y agoCustom stackless coroutine schedulers are also available in Kotlin. Python also also allows you to customize the event loop, I think, but overriding AbstractEventLoop. A M:N implementation would probably be inefficient though because of the GIL. Basically almost all stackless implementations I know allow for custom scheduling. The fact that some of them can't do M:N and are restricted to 1:N is just a limitation of dynamic programming languages. There is a global interpreter state which prevents you from using multiple OS threads efficiently. You either rely on GIL (CPython and Ruby MRI) or rely on just allow only one thread (Node, Lua). So GP is right in that not _all_ async/await implementations will allow you to fully customize your threads but I think the main point here is that stackless coroutines are practically _a prerequisite_ for enabling custom scheduling (like C# et. al allow). You cannot have this custom scheduling with stackful coroutines, because that would require the scheduler to have access to low level memory management for controlling the stack. I've never seen a language which allows that. I guess this could be doable on C++, but I really don't see the point, since it will require a lot more effort than the current stackless C++ coroutines.
- pjmlp 6y agoThat is my whole point, this is not doable with Go channels alone as primitive.
- gpderetta 6y agoYes, that's not a good primitive. You need some delimited form of call/cc.
- gpderetta 6y ago> I've never seen a language which allows that. It is not really hard. You can use the exact same scheduler you would use for stackless coroutines. For example in C++ land you can use boost.asio to schedule both stackless coroutines and boost.fibers (or whatever have you). Boost.asio predates both and doesn't care.
- unscaled 6y agoSomething that looks like async/await and has a rather bad performance can be implemented through channels. Nestable stackless coroutines cannot. By definition they require compiler support. Your proposed solution will not have any of the advantages of stackless coroutines (effect typing of async functions and perfectly optimal memory use) while suffering all the performance penalty of running on top of a channel.
- YetAnotherNick 6y agoChannels have close to zero performance penalty. If you are talking about goroutines, you need to come up with data or code. I found goroutines to be really cheap to create.
- unscaled 6y agoNot true: https://www.jtolio.com/2016/03/go-channels-are-bad-and-you-should-feel-bad/#channels-are-slower-than-implementing-it-yourself:7de476e370ca6a780a51fd680c5a51dd https://www.jtolio.com/2016/03/go-channels-are-bad-and-you-s... I'm pretty sure the implementation has seen some improvements since then. But using a channel for async await is the same as using a global mutex every time you await. That is bound to be contentious on high load.
- Taek 6y agoI think today channels cost a few hundred nanoseconds. For most applications, this is 'close to no overhead'. If you are doing a really tight loop of course or have threads that bump into eachother a million times per second, you're going to want a different primitive. But most programmers aren't going to see any overhead using channels instead of something else.
- unscaled 6y agoPlease remember the approach is "every context switch should go through a centralized channel". This including waiting on all other channels. I need to see some benchmark to this level to be proven the overhead is negligible. And of course, there is still the question of WHY would you ever want to do that. What can be gained from simulating an async-await model on top of a channel.