2 ms·
Didn't see your comment til now. So, here is the difference I see: Full-blown coroutines give us a way to write fully asynchronous code without using callbacks
by iambvk 13y ago
Didn't see your comment til now. So, here is the difference I see:
Full-blown coroutines give us a way to write fully asynchronous code without using callbacks. For example, I could define ASYNC macro as follows:
#define ASYNC(blocking_function_call) \
do { \
auto io_pool = GetIOThreadPool(); \
auto cpu_pool = GetCurrentThreadPool(); \
\
Detach_The_Thread_and_Enqueue_Coroutine_For_IO(io_pool); \
\
blocking_function_call; \
\
Detach_The_Thread_and_Enqueue_Coroutine_For_CPU(cpu_pool); \
} while (0)
Now, I can make any blocking operation asyncrhonous. For example, open() or readdir() functions do not have asynchronous interfaces, but I can make them asynchronous by simply wrap it with ASYNC(...) macro.
It works as follows: When we need to do a blocking operation, we suspend the coroutine and we enqueue it into a thread-pool that is designated to do blocking calls; the cpu thread is now free, so it can start executing other cpu-bound coroutines. When io thread has finished the job, it will enqueue the coroutine back to the CPU thread pool.
What we have now is a fully asynchronous system where cpu threads can be kept busy with only cpu-bound work and io threads can be kept with io-bound work. This gives us full control over the concurrency. We could be confident that CPU threads are always available for compute work.
We cannot do this with python "yield".