2020-10-13 09:06:29
Python并发编程可通过多线程、多进程、线程池/进程池、协程(asyncio)等方式实现,不同技术适用于不同场景,需根据需求选择合适方案。以下是具体介绍:
一、线程篇使用threading模块创建线程,通过继承Thread类或直接实例化并传入目标函数。
使用Lock、RLock、Semaphore等同步原语解决竞态条件,例如对共享资源的访问控制。
示例代码结构:
import threadinglock = threading.Lock()def task(): with lock: # 操作共享资源 passthread = threading.Thread(target=task)thread.start()使用multiprocessing模块创建进程,支持Process类、Pool池化技术。
通过Queue、Pipe或Manager实现进程间通信,例如传递数据或同步状态。
示例代码结构:
from multiprocessing import Process, Queuedef task(q): q.put("result")q = Queue()process = Process(target=task, args=(q,))process.start()print(q.get())使用concurrent.futures.ThreadPoolExecutor或ProcessPoolExecutor。
通过submit()提交任务,map()批量提交,future.result()获取结果。
示例代码结构:
from concurrent.futures import ThreadPoolExecutordef task(x): return x * xwith ThreadPoolExecutor(max_workers=4) as executor: results = executor.map(task, [1, 2, 3])print(list(results))事件循环(Event Loop):管理协程的执行与调度。
协程函数(async def):定义异步任务,需通过await挂起。
任务(Task):封装协程,提交至事件循环执行。
使用asyncio.run()启动事件循环。
通过asyncio.gather()并发运行多个协程。
示例代码结构:
import asyncioasync def fetch_data(): await asyncio.sleep(1) # 模拟I/O操作 return "data"async def main(): results = await asyncio.gather(fetch_data(), fetch_data()) print(results)asyncio.run(main())使用aiohttp发送异步HTTP请求。
通过asyncio.Queue管理待抓取URL队列。
示例代码结构:
import aiohttpimport asyncioasync def fetch(url): async with aiohttp.ClientSession() as session: async with session.get(url) as response: return await response.text()async def main(): urls = ["兼容性:依赖猴子补丁(monkey.patch_all())修改标准库,可能引发不可预测的副作用。
调试难度:协程切换由底层C库控制,错误堆栈难以追踪。
生态限制:部分第三方库未适配Gevent,导致性能下降或功能异常。