Python 进程、线程与协程(从原理到实践的完整指南)

发布时间:2026/5/20 7:03:36

Python 进程、线程与协程(从原理到实践的完整指南) 前言在学习 Python 并发编程时进程、线程、协程是必须掌握的三大核心技术。很多初学者往往只会写代码但不理解底层原理导致在实际开发中选型错误、性能低下。本文将结合实际案例从概念 → 原理 → 代码 → 进阶知识逐步讲解帮助你真正理解并发编程。一、多任务基础理解并发的前提1. 什么是多任务多任务指的是同一时间执行多个任务例如一边下载文件一边听音乐浏览器同时打开多个网页2. 并发 vs 并行重点并发一段时间内“交替执行”单核CPU看起来同时执行实际是快速切换并行同一时刻“真正同时执行”多核CPU多个任务真正同时运行核心理解并发是“假同时”并行是“真同时”二、进程1. 进程的本质进程是操作系统分配资源的基本单位特点独立内存空间相互隔离稳定但开销大2. 多进程实现frommultiprocessingimportProcessimporttimedeftask(name):foriinrange(3):print(f{name}执行中...)time.sleep(0.5)if__name____main__:p1Process(targettask,args(任务A,))p2Process(targettask,args(任务B,))p1.start()p2.start()p1.join()p2.join()说明start()启动进程join()等待执行完成3. 进程参数传递deffunc(a,b):print(a,b)pProcess(targetfunc,args(1,2))p.start()或pProcess(targetfunc,kwargs{a:1,b:2})4. 获取进程ID进阶importosprint(os.getpid())# 当前进程print(os.getppid())# 父进程用于调试和进程管理5. 进程核心难点数据不共享frommultiprocessingimportProcess data[]defadd():data.append(1)print(子进程:,data)if__name____main__:pProcess(targetadd)p.start()p.join()print(主进程:,data)输出子进程: [1] 主进程: []原因子进程是主进程的“副本”各自操作不同内存6. 守护进程进阶pProcess(targettask)p.daemonTruep.start()主进程结束 → 子进程自动结束三、线程1. 线程是什么线程是CPU调度的基本单位是进程中的执行单元一个进程至少有一个线程2. 多线程基本使用importthreadingimporttimedeftask():foriinrange(3):print(执行任务)time.sleep(0.5)t1threading.Thread(targettask)t2threading.Thread(targettask)t1.start()t2.start()t1.join()t2.join()3. 线程参数传递deffunc(name):print(name)tthreading.Thread(targetfunc,args(Python,))t.start()4. 线程共享数据重点importthreading num0defadd():globalnumfor_inrange(100000):num1t1threading.Thread(targetadd)t2threading.Thread(targetadd)t1.start()t2.start()t1.join()t2.join()print(num)结果不一定正确原因数据竞争5. 线程锁进阶重点importthreading num0lockthreading.Lock()defadd():globalnumfor_inrange(100000):withlock:num1threads[threading.Thread(targetadd)for_inrange(2)]fortinthreads:t.start()fortinthreads:t.join()print(num)保证线程安全6. 线程执行顺序易错点线程执行是无序的由操作系统调度7. GIL关键难点Python 存在 GIL同一时间只能有一个线程执行字节码多线程无法利用多核CPU结论场景推荐CPU密集型多进程IO密集型多线程四、协程1. 协程是什么协程是用户态的轻量级线程特点由程序控制调度切换开销极小适合高并发IO2. async / await 基础importasyncioasyncdeftask():print(开始)awaitasyncio.sleep(1)print(结束)asyncio.run(task())3. 协程并发执行importasyncioasyncdeftask(name):print(f{name}开始)awaitasyncio.sleep(2)print(f{name}结束)asyncdefmain():tasks[task(f任务{i})foriinrange(3)]awaitasyncio.gather(*tasks)asyncio.run(main())总耗时 ≈ 2秒4. 事件循环核心原理协程运行依赖Event Loop事件循环遇到await主动让出执行权本质单线程 IO多路复用5. 协程进阶任务调度asyncdefmain():t1asyncio.create_task(task(A))t2asyncio.create_task(task(B))awaitt1awaitt26. 协程实战异步爬虫importaiohttpimportasyncioasyncdeffetch(url):asyncwithaiohttp.ClientSession()assession:asyncwithsession.get(url)asres:returnawaitres.text()asyncdefmain():urls[https://example.com]*3tasks[fetch(url)forurlinurls]resultsawaitasyncio.gather(*tasks)print(len(results))asyncio.run(main())高并发网络请求场景7. 协程注意事项进阶不要使用time.sleep()会阻塞CPU密集任务不适合协程Python3.7 推荐asyncio.run()五、三者核心对比必须掌握特性进程线程协程内存独立共享共享开销大中小并行支持受限不支持调度OSOS用户场景CPU密集IO密集高并发IO六、选型指南实战一句话总结计算密集 → 多进程普通IO → 多线程高并发IO → 协程七、常见误区总结❌ 线程一定比进程快 错CPU任务反而更慢❌ 协程是多线程 错本质还是单线程❌ 多线程就是并行 错受GIL限制八、总结进程重量级稳定适合计算线程共享资源适合IO协程极轻量高并发利器最重要的理解进程解决“多核利用”线程解决“资源共享”协程解决“高并发IO”

相关新闻