in the past, I used to put future directly into eventloop to perform run_until_complete, interview. When an interviewer asked me how to schedule the program, I was completely confused. May I ask how you are dispatched?
in the past, I used to put future directly into eventloop to perform run_until_complete, interview. When an interviewer asked me how to schedule the program, I was completely confused. May I ask how you are dispatched?
Chinese dictionary interpretation, scheduling for management and arrangement. For a coroutine, schedule, it's not just run_until_complete
-- it's just arranged to start a coroutine immediately and wait until it's complete; during the execution of the coroutine, you don't manage or schedule the details of the coroutine yourself. What the interviewer wants you to answer is how event loop will schedule coroutine after it takes over.
for Python, coroutine in a narrow sense refers to an instance of coroutine
, which is usually the return value of calling a async def
function, for example:
priority queue _ scheduled
in
goes back to main ()
, where await
returns the Future
instance that slept for 1 second to the previous send ()
call;
Task._step ()
finds that an instance of Future
has been received, and immediately calls its add_done_callback ()
to register the steps to be continued in the future.
go back to the main event loop loop and continue to execute loop._run_once ()
; next time.
this time the _ ready
queue is empty, but there is something in the _ scheduled
priority queue. Event loop will check whether the recently planned TimerHandle
is due to be executed-obviously we have just scheduled it for a second before execution, so we will not execute immediately, but calculate how long we should wait before execution (it will be slightly shorter than 1 second because other code has been run after the schedule);
calls selector.select ()
and takes the above time as the timeout parameter. The call blocks for nearly 1 second because no other Iamp O events are registered;
execute loop._run_once ()
for the third time, and find a TimerHandle
is due, execute it immediately;
flip through the previous steps. This TimerHandle
will call sleep
to generate Future
instance set_result ()
; .
once the Future
instance has a result, it will then trigger the execution of the previously registered done callback, that is, resume the execution of Task
.
in the new Task._step ()
call, Task
will call coro.send ()
again to finish executing the remaining return 123
in main ()
.
the result returned here 123
will be used by Task
to call self.set_result
. After all, Task
is the earliest Future
instance;
looking back at step 3, this Future
instance has been added by run_until_complete
with a done callback, function to stop event loop. So, at this point, event loop will be set to be stopped;
The execution of TimerHandle
is completed and enters the next main loop, but because event loop has been set to be stopped, the main loop ends because the condition is not met. loop.run_forever ()
is returned.
goes back to the original run_until_complete ()
, which returns future.result ()
, that is, 123
, and finally assigns a value to rv
.
to sum up, event loop's scheduling of callback is preemptive: _ scheduled
if there is a time in the priority queue, the first-come-first-served callback will be executed first, and then the callback will be executed on a first-come-first-served basis, and all the callbacks will be executed as long as there is a callback in the _ ready
queue, so as to repeat until someone actively stops event loop. Finally, a coroutine is executed by multiple callbacks driven by Task
, and the split point is await
; for multiple concurrent coroutine, macroscopically, the scheduling method is "who executes a segment first when the time is up, or who executes a segment first when there is progress in the Icode O event, or who registers first".
Previous: What should we do if we traverse the matrix like this?
Next: Npm install gulp-- save-dev Times error, but report git error, as shown in the figure