I am trying to understand the new async coroutines (introduced in Python 3.5).
In 1997 I attended a course at university which roughly covered the content of the book Modern Operating Systems by Andrew Tanenbaum.
Somehow the await
in Python3 reminds me at Cooperative Multitasking.
From Wikipedia:
Cooperative multitasking, also known as non-preemptive multitasking, is a style of computer multitasking in which the operating system never initiates a context switch from a running process to another process. Instead, processes voluntarily yield control periodically or when idle in order to enable multiple applications to be run simultaneously. This type of multitasking is called "cooperative" because all programs must cooperate for the entire scheduling scheme to work.
If you look at the Python interpreter like an operating system, does the term "Cooperative Multitasking" apply to await
?
But may be I am missing something.
It is cooperative multitasking indeed.
What about a small program to prove it. Let's first sleep with cooperative
asyncio.sleep
for a second and then let's sleep with blockingtime.sleep
for a second. Let's print a thread id, time spent in the coroutine and id of a task.Now let's try and see:
As expected. Execution was only in one thread.
asyncio.sleep(1)
is nonblocking, so it took 1 second to process all of them concurrently.time.sleep(1)
is blocking (it does not cooperate), so it blocks the rest. Id1
waits for id2
to finish while id2
waits for id3
to finish.C# has async/await too, does it have cooperative multitasking as well?
Let's try the same thing in C#:
Run it and...
Damn. The threads are different after await. And it tooks just 2 seconds for each of the coroutine! What's wrong?
Nothing is wrong. Unlike Python, async/await in C# has a combination of cooperative multitasking and multithreading.
Task.Delay(1000)
is indeed nonblocking but when a coroutine resumes, it can resume in a totally different thread as it did in the example. Since the coroutines continued in three different threads,Thread.Sleep(1000)
blocked them in parallel.Note there are more things in C# which can influence this behavior (like SynchronizationContext), but this is a different topic.
A coroutine can pause execution using the await keyword with another coroutine. While it is paused, the coroutine’s state is maintained, allowing it to resume where it left off the next time it is awakened. That sounds quite like Cooperative multitasking to me. See this example
Yes. According to Wikipedia: