资讯动态

理解python进程

发布时间:2026/8/18 12:37:45 来源:尧图企业网站定制
进程 - CPU密集型王者概述操作系统资源分配的基本单位注意这里的 资源分配 只是分配资源硬件多核前提下Python multiprocessing 多进程可以实现真正并行单进程只能并发无法并行python的多进程会真正启动底层的多个系统进程每个进程拥有独立的内存空间和完整的python解释器状态这完美规避了全局解释器锁(GIL)的限制能够真正利用多核CPU理解多进程中的每个进程都是单线程 / 多进程中的每个进程都是多线程 哪种能规避GIL限制结论只有多进程中的每个进程都是单线程能规避解释multiprocessing 开辟多个操作系统进程每一个进程内部都拥有独立 Python 解释器、独立 GILGIL 的生效范围仅局限当前进程内部进程和进程互不影响举例场景 A每个子进程只开 1 条线程进程内只有一个线程不存在线程争抢 GIL。操作系统可以把多个进程调度到多核真正并行执行 CPU 任务充分规避 GIL 瓶颈场景 B某一个子进程内部继续创建多条threading线程⚠️ 这个进程内部依旧受本进程自带 GIL 约束在同一个进程里面无论你开多少线程同一时刻依旧只能一条线程执行 CPU 计算。认识GILGIL 属于单个 Python 解释器实例一个进程对应一套解释器、一把 GIL多进程方案能利用多核本质是多个独立进程可被调度到不同 CPU 核心如果某个进程内部使用多线程该进程内部依旧无法并行计算逃不开当前进程的 GIL所以做 CPU 密集运算的最佳实践每个工作进程保持单线程多进程适用场景适合干那些极耗费脑力/体力的活 例如图像处理、加密解密、大规模矩阵预算计算缺点创建进程太重了消耗内存大多进程演示importmultiprocessingimporttimedefcalculate_heavy_task(name):print(f进程{name}开始疯狂计算...)time.sleep(2)# 模拟耗时计算print(f进程{name}计算完成)if__name____main__:starttime.time()# 创建两个独立的进程p1multiprocessing.Process(targetcalculate_heavy_task,args(A,))p2multiprocessing.Process(targetcalculate_heavy_task,args(B,))p1.start()p2.start()p1.join()p2.join()endtime.time()print(所有计算任务结束,end-start)深度剖析 - 进程的作用线程才是真正干活的也能调用多核心那把“进程”这个概念完全砍掉让所有线程直接在操作系统里裸奔不是更轻量、更直接吗结论如果只有线程计算机一天得崩溃一百次。线程虽然会干活但它是个“没家产、没记性、没边界”的打工人。进程的出现本质上是为了给线程提供“生存空间”、“保护伞”和“规矩”。资源分配的“大管家”给线程分家产线程自己是几乎不拥有任何系统资源的。它没有独立的内存不知道哪里可以存数据。进程当你启动一个程序时进程负责向操作系统申请大笔的“家产”——包括独立的虚拟内存空间堆、代码段、数据段、打开的文件句柄、网络套接字、环境变量等。线程怎么用进程申请到这笔家产后住在里面的所有线程共享这笔家产。如果没了进程这个大管家线程一出生就两眼一抹黑连把变量存在内存的哪个地方都不知道。内存隔离的“防火墙”防止线程互相投毒这是有进程最关键的物理原因安全与稳定性。如果只有线程所有软件的线程都混在同一个内存池里。某天你写了一个有 Bug 的 C 线程不小心写错了一个指针比如野指针直接把隔壁微信线程或者银行支付线程的内存数据给覆盖抹掉了。这不仅会导致系统极度不稳定还带来了致命的隐私和安全隐患。有了进程之后操作系统给每个进程划分了绝对隔离的虚拟内存地址空间。微信进程只能访问微信的内存。浏览器进程只能访问浏览器的内存。底层铁律进程 A 的线程绝对不可能直接去读写进程 B 的内存。如果某个线程敢越界操作系统的硬件保护机制MMU会当场触发“段错误Segmentation Fault”直接把这个犯规的进程一枪干掉而其他进程毫发无损。代码演示# 进程防火墙的例子importthreadingimporttime# 全部线程共享同一进程内的全局变量共享内存区域 account_balance1000# 银行支付线程使用wechat_msg_cache[]# 微信线程使用# 线程1银行支付线程持续扣款defbank_pay_thread():globalaccount_balancefor_inrange(10):ifaccount_balance100:account_balance-100print(f【支付线程】扣款成功当前余额{account_balance})time.sleep(0.01)# 线程2微信线程持续接收消息存入缓存defwechat_thread():globalwechat_msg_cacheforiinrange(10):wechat_msg_cache.append(f消息{i})print(f【微信线程】存入消息缓存长度{len(wechat_msg_cache)})time.sleep(0.01)# 线程3有BUG的线程无保护并发胡乱修改共享全局数据# 类比C野指针乱覆盖隔壁线程内存defbug_thread():globalaccount_balance,wechat_msg_cachefor_inrange(8):# 恶意/错误篡改支付线程的余额数据account_balance0# 清空微信线程的消息缓存wechat_msg_cache.clear()print(【BUG线程】篡改了共享内存里的数据)time.sleep(0.02)if__name____main__:t1threading.Thread(targetbank_pay_thread)t2threading.Thread(targetwechat_thread)t3threading.Thread(targetbug_thread)t1.start()t2.start()t3.start()t1.join()t2.join()t3.join()print(\n最终结果)print(f账户余额 {account_balance})print(f微信消息列表 {wechat_msg_cache})权限与身份的“代言人”防止流氓软件越权操作系统在管理安全策略时只认进程不认线程。你在电脑上右键“以管理员身份运行”或者在手机上弹窗提示“是否允许微信访问相册”这个权限是赋予进程的。进程就像是一张“通行证”。有了这张通行证住在这个进程里的所有打工线程才能合法地去读写特定文件、访问网络。如果只有线程操作系统根本没办法精细地管理哪个线程是安全的、哪个线程是木马病毒。软件层面的“生命周期管理”从开发和维护的角度来看进程是软件存在的最小实体。你在任务管理器里看到的、能手动“结束任务”的都是进程。如果一个复杂的软件包含几百个线程卡死了你只需要在任务管理器里把这个进程杀掉操作系统就会自动回收这个进程持有的所有内存、关闭它打开的所有文件干净利落。如果只有线程你可能得在几千个乱七八糟的线程里苦苦寻找哪几个是属于刚才那个卡死软件的根本无法管理。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价