python多进程:fork, spawn, forkserver模式
-
fork模式
1.仅unix系统支持,并且是unix系统的默认模式.
2.使用该模式创建子进程的时候,会复制父进程的全部变量,支持传参(任意类型)给子进程,但是不会复制父进程的线程.
3.该模式相当于将父进程的内存复制一份用于创建子进程.但是由于不复制线程的特点,当父进程存在多线程的时候,可能会带来安全问题(复制了线程锁,而没有复制解锁的线程过去,容易触发死锁).同时,由于不管用不用得上的资源都将被复制到子进程,所以可能会带来"膨胀"问题,占用更多的内存.
4.由于该模式是复制父进程的内存,所以启动方式更快.
5.该模式可以在任意地方创建子进程. -
spawn模式
1.unix,windows,mac都支持,并且是windows和mac的默认启用模式.其中windows只支持该模式.
2.该模式只能在"__main__"方法下开启多进程.
3.使用该模式创建子进程的时候,会重新生成一份与入口方法相关的变量,所以在父进程中存在,而子进程中未创建的变量,在子进程内是不存在的.可以简单理解为,创建子进程的时候,会重新执行一次main方法之外的代码.
4.该模式支持传参到子进程,但是不支持传递某些特殊资源到子进程,如:文件对象,文件句柄,线程锁等.这类资源需要子进程自主创建.
5.这种模式启动更慢,但是可能会更节省内存.搭配共享内存使用可能会更佳. -
forkserver模式
主进程启动时,预先创建一个干净的"forkserver"进程,仅加载了必要的python解释器和基础模块.
需要创建子进程的时候,主进程unix socket通知forkserver,由forkserver调用fork()生成子进程.
子进程集成forkserver的初始状态,而非主进程的实时内存.
特点:
1.避免直接继承主进程的多线程状态或锁,减少死锁风险
2.后续子进程通过 fork() 快速创建,无需重复加载模块(相比 spawn)
3.仅支持 Unix 系统(因为依赖 fork()),Windows 不可用
4.首次启动慢,因为需要创建forkserver进程,后续启动快,安全性高,内存使用量小,算是spawn和fork模式的折中做法
5.必须在"__main__"方法下调用,避免递归创建 - 总结对比
fork启动快,有引起意外死锁风险和内存膨胀问题;
spawn启动慢,仅加载使用到的模块,内存占用小;
forkserver折中,有forkserver的额外开销,首次启动慢,后续启动快,内存占用中等,需要频繁开关进程的场景优势最大.