Async code and the event loop
لم يُترجم بعد؛ يُعرض باللغة الإنجليزية
Most of a download is waiting: for the network, for the disk. Async code puts that waiting to use. Watch Python's event loop run three downloads on one thread, one task at a time, parking each task while it waits and resuming it when its data is ready, so all three finish in about the time of the slowest.
5 أسئلة سريعة
اختر إجابة لتعرف السبب. تُحفَظ نتيجتك مع تقدّمك.
01Three downloads take 2, 4 and 5 seconds. Run with asyncio.gather(), about how long does the whole program take?
The waits overlap on one thread, so the program finishes when the slowest download does: about 5 seconds. One after another would take 2 + 4 + 5 = 11 seconds.
02What does await do inside an async def function?
await marks a point where the coroutine may pause. While it is parked, the event loop runs other tasks; when the result is ready, the task resumes on the line after await.
03How many tasks does an asyncio event loop run at the same moment?
The loop runs on one thread and runs one task at a time. Tasks take turns, switching only at await.
04A task inside an async program runs a long calculation that never awaits. What happens?
A task only hands the loop back at await, so CPU-heavy work holds the loop. Run it in a worker process instead, for example with loop.run_in_executor().
05In JavaScript, what does fetch(url) give back straight away?
fetch() returns a Promise at once. await (inside an async function) or .then() with a callback gets the result when it is ready.
المسرد
- Asynchronous (async) code
- Code that can start a slow operation, such as a download, and do other work while it waits instead of standing still.
- Event loop
- A loop on one thread that runs ready tasks one at a time and resumes waiting tasks when what they wait for is done.
- Coroutine
- A function defined with async def that can pause at await and carry on later from the same spot.
- await
- Marks where a coroutine may pause until something it needs, such as data from the network, is ready.
- Task
- A coroutine that has been handed to the event loop to run, for example by asyncio.gather().
- Promise
- A JavaScript object standing for a result that arrives later; await or .then() gets the value when it does.
- Callback
- A function you pass to other code so it can be called later, for example when a download finishes.
- Blocking
- Holding the thread so nothing else can run, as a long calculation or time.sleep() does.
الملاحظات والمصادر
- asyncio.sleep() stands in for a network wait. A real download would use asyncio streams or a library such as aiohttp, and the loop treats it the same way: the task parks until its data arrives.
- Strictly, the ready queue holds callbacks, not tasks. A parked task is resumed by a callback that runs its next step, which the loop schedules with call_soon() once the thing it awaits is done.
- While every task is parked, the loop asks the operating system which sockets are ready (select, epoll or kqueue, through Python's selectors module) and sleeps until one is, or until the next timer is due.
- About 3 seconds: a little more in practice, because starting tasks and switching between them takes a small amount of time.
- The full program also needs import asyncio at the top and asyncio.run(main()) at the bottom; asyncio.run() starts the event loop and runs main() on it.
- Async code is concurrent but not parallel: one thread does all the work and switches only at await. That suits many slow network waits, and does not speed up heavy calculation.
- Python docs: Coroutines and tasks (asyncio)
- Python docs: Event loop (asyncio)
- Python docs: Developing with asyncio, running blocking code
- Python docs: selectors, waiting on many sockets
- PEP 492: Coroutines with async and await syntax
- MDN: JavaScript execution model (the event loop)
- MDN: Promise
- MDN: async function
- MDN: Callback function
اختبار يتاح بعد الخطوة الأخيرة.