asyncio 运行流程:
-
创建事件循环:使用 asyncio.get_event_loop() 或 asyncio.new_event_loop() 创建事件循环。
-
定义异步任务:使用 async def 定义异步函数,或使用 asyncio.ensure_future() 或 loop.create_task() 创建任务。
-
运行事件循环:使用 loop.run_until_complete() 运行事件循环,直到所有任务完成。
-
完成处理:当所有任务完成或被取消时,事件循环结束。
import asyncioasync def main(): try: print("Start executing asynchronous tasks") await asyncio.sleep(2) # Simulate asynchronous task print("Finished executing asynchronous tasks") except asyncio.CancelledError: print("Task was cancelled") # Create event loop loop = asyncio.get_event_loop() # Run asynchronous tasks task = loop.create_task(main()) # Cancel the task after 1 second loop.call_later(1, task.cancel) # Run event loop indefinitely loop.run_forever() # The event loop runs until it is explicitly stopped or an exception is encountered, so the main thread is blocked
-
处理任务:事件循环在异步函数中遇到 await 时挂起当前任务,直到等待的异步操作完成,然后继续执行。
import asyncio
import timeasync def main(): print("Start sleeping") await asyncio.sleep(3) # 异步等待3秒 print("Finished sleeping") # 在主线程中运行事件循环 loop = asyncio.get_event_loop() loop.run_until_complete(main()) # 等待异步任务完成
threading 运行流程:
-
创建线程:使用 threading.Thread 创建新线程对象,传入 target 参数指定运行的函数。
-
启动线程:调用线程对象的 start() 方法启动线程,此时线程处于就绪状态。
-
线程执行:在指定函数中执行需要的操作。
-
线程完成:当函数执行完毕或调用 threading.Thread 对象的 join() 方法等待线程执行完毕。
-
线程结束:线程执行完毕后自动结束。
import threading
import time# Define a function that takes parameters def thread_task(message): print("Thread is executing with message:", message) time.sleep(2) # Simulate some task print("Thread execution finished") # Create a new thread with parameters message = "Hello, threading!" thread = threading.Thread(target=thread_task, args=(message,)) # Start the thread thread.start() # Wait for the thread to finish execution thread.join() print("Main thread execution finished")
主线程同时运行 asyncio 和 threading 的注意事项:
- 事件循环与线程:asyncio 的事件循环是单线程的,不能直接在多线程中使用。可以通过 loop.run_in_executor() 在单独的线程中运行阻塞操作。
- 线程安全:asyncio 大部分 API 不是线程安全的,因此应在主事件循环中使用。
- 主线程 :主线程结束时,asyncio 的事件循环也会随之结束。这是因为主线程是启动事件循环的线程,当主线程结束时,事件循环也会被终止。如果在 asyncio 中执行了阻塞的同步操作,或者在主线程中等待 asyncio 任务完成而不使用异步方式(如 loop.run_until_complete(),run_until_complete 方法会阻塞主线程,直到传入的 Future 或协程完成为止),那么可能会导致主线程被阻塞。