【Python】举个例子说明如何通过asyncio实现并发

【Python】举个例子说明如何通过asyncio实现并发
最新回答
素颜繁华梦

2026-10-21 16:24:00

以下通过一个具体示例说明如何使用asyncio实现并发,并对比同步执行及常见错误场景。

1. 正确实现并发的示例import timeimport asyncioasync def function_1(): print("Function 1 started.") while True: print("1", int(time.time())) await asyncio.sleep(3) # 模拟I/O操作,释放控制权async def function_2(): print("Function 2 started.") while True: print("2", int(time.time())) await asyncio.sleep(2) # 模拟I/O操作,释放控制权if __name__ == "__main__": loop = asyncio.get_event_loop() tasks = [loop.create_task(function_1()), loop.create_task(function_2())] loop.run_until_complete(asyncio.gather(*tasks)) # 并发执行关键点说明:
  • 异步函数:通过async def定义协程函数,使用await挂起当前任务(如asyncio.sleep)。
  • 事件循环:loop.run_until_complete启动事件循环,asyncio.gather并发运行多个任务。
  • 并发效果:

    function_1等待3秒时,事件循环切换到function_2执行2秒,交替进行。

    输出中1的时间间隔为3秒,2的时间间隔为2秒,证明两者交替执行。

2. 同步执行的对比(无并发)

若移除asyncio相关代码:

def function_1(): print("Task 1 started.") while True: print("1", int(time.time())) time.sleep(3) # 阻塞线程def function_2(): print("Task 2 started.") while True: print("2", int(time.time())) time.sleep(2)if __name__ == "__main__": function_1() # 阻塞,function_2永远无法执行 function_2()结果分析:
  • 单线程阻塞:function_1的time.sleep(3)会阻塞整个线程,导致function_2无法启动。
  • 输出:仅打印1的时间戳,2的输出永远不会出现。
3. 常见错误场景错误1:未启动事件循环async def function_1(): ...async def function_2(): ...if __name__ == "__main__": function_1() # 报错:协程未被驱动
  • 问题:直接调用协程函数不会执行,必须通过事件循环(如loop.run_until_complete)。
错误2:顺序执行而非并发async def main(): await function_1() # 等待function_1完成 await function_2() # 再执行function_2if __name__ == "__main__": asyncio.run(main()) # 实际是顺序执行
  • 问题:main()中顺序await导致任务无法交替,需通过asyncio.gather或create_task实现并发。
4. 核心原理总结
  • 协程与事件循环:

    协程通过await主动释放控制权,事件循环利用这一机制切换任务。

    单线程内实现“并发”效果,避免线程切换开销。

  • 与多线程的区别:

    asyncio是协作式多任务(任务主动让出控制权),而多线程是抢占式(由操作系统调度)。

5. 正确代码的输出示例Function 1 started.1 1646665447Function 2 started.2 16466654472 16466654491 16466654502 16466654511 1646665453...
  • 验证并发:1和2交替出现,时间戳间隔符合各自sleep时间。

通过以上示例和对比,可以清晰理解asyncio实现并发的关键步骤及常见误区。