You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于Python 3.6中Asyncio并发原理及代码实现的疑问

Hey there! Let's break down where your understanding of asyncio might be off, and why your code is running synchronously instead of concurrently.

How Asyncio's Concurrency Actually Works

First, let's clarify a core point: asyncio uses a single-threaded event loop. When you await something, the current coroutine pauses only if the thing you're awaiting is an asynchronous operation that yields control back to the event loop. If the operation doesn't yield control (like a blocking sync function), the event loop can't switch to other coroutines—so everything runs one after another.

Your initial thought is partially right: await does pause the current coroutine, but only when it's waiting on something that lets the event loop do other work. If you're awaiting a blocking task, the loop gets stuck waiting for that task to finish before moving on.

Why Your Code Is Running Synchronously

Chances are, your code falls into one of two common traps:

  1. You're awaiting a synchronous blocking function (like time.sleep(), or a sync database call) instead of its async equivalent.
  2. You're awaiting coroutines one after another in sequence, instead of launching them as concurrent tasks.

For example, here's a typical "broken" version that runs synchronously:

import asyncio
import time

async def slow_task(name):
    print(f"Starting {name}")
    time.sleep(2)  # This is a BLOCKING sync call! It doesn't yield control.
    print(f"Finishing {name}")

async def main():
    # Awaiting one task at a time forces sequential execution
    await slow_task("Task 1")
    await slow_task("Task 2")
    await slow_task("Task 3")

asyncio.run(main())

This code will take 6 seconds total, because each time.sleep(2) blocks the entire event loop—no other coroutines can run while it's sleeping.

Fixing the Code to Run Concurrently

To make it work as expected, you need two changes:

  • Replace blocking sync operations with async alternatives (like asyncio.sleep() instead of time.sleep()).
  • Launch multiple coroutines as concurrent tasks so the event loop can switch between them.

Here's the corrected version:

import asyncio

async def slow_task(name):
    print(f"Starting {name}")
    await asyncio.sleep(2)  # Async sleep yields control to the event loop
    print(f"Finishing {name}")

async def main():
    # Use asyncio.gather() to run tasks concurrently
    await asyncio.gather(
        slow_task("Task 1"),
        slow_task("Task 2"),
        slow_task("Task 3")
    )

    # Alternatively, create tasks explicitly first:
    # task1 = asyncio.create_task(slow_task("Task 1"))
    # task2 = asyncio.create_task(slow_task("Task 2"))
    # task3 = asyncio.create_task(slow_task("Task 3"))
    # await task1
    # await task2
    # await task3

asyncio.run(main())

This code will take only 2 seconds total—all three tasks start at nearly the same time, and when each hits await asyncio.sleep(2), it yields control back to the event loop, which can run the other tasks until their sleep is done.

Key Takeaways to Remember
  • await pauses the current coroutine only when the awaited object is an async operation that yields control. Blocking sync code won't let this happen.
  • To run coroutines concurrently, don't await them one after another—use asyncio.gather() or asyncio.create_task() to schedule them all at once.
  • Asyncio's concurrency is about cooperative multitasking: coroutines have to voluntarily give up control (via awaiting async operations) for the event loop to switch to other work.

内容的提问来源于stack exchange,提问作者N Fembrianto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:18:49