概述
python的multiprocessing.Process类用于创建进程,并且是跨平台的,在windows、unix、linux、Mac OS等操作系统中都可用
本篇文章主要讲解Process类的源码,以及分析是如何实现跨平台的
Process类的位置
在python库的multiprocessing包中没有Process类,如下图:
查看__init__.py文件
在python中,包中的__init__.py是重要文件,查看__init__.py文件,该文件代码很少,如下图:
红框处代码,通过__all__暴露出接口,也就是说暴露的接口在context文件的_default_context变量中
下面代码
from . import context
中的.表示当前目录,也就是说,context.py文件位于当前包目录下
接下来打开context.py文件,找到_default_context变量
查看context.py文件
该文件在github中有源代码,链接:
http://www.malaoshi.top/show_1EF2n0bV2eEJ.html
讲解context.py源代码:
30行,定义BaseContext类
219行,定义Process类,继承process.BaseProcess类,定义静态方法
_Popen(),这里是关键225行,定义DefaultContext类,继承BaseContext类,定义类属性Process
264行,定义
DefaultContext.__all__,由于DefaultContext类有类属性Process,所以__all__中有Process270行,通过
sys.platform判断操作系统平台,如果当前操作系统是windows,执行317行代码,如果是其他操作系统就执行272行代码317行,定义
SpawnProcess类,继承process.BaseProcess类,定义静态方法_Popen,在该方法中引入.popen_spawn_win32.Popen,并返回Popen对象324行,定义
SpawnContext类,继承BaseContext类328行,定义
_concrete_contexts变量,dict类型,将SpawnContext类对象作为value放入,对应的key是fork331行,创建
DefaultContext对象,并传入SpawnContext类对象,定义变量_default_context,指向上面的对象272-277行代码,创建ForkProcess类,该类是BaseProcess的子类,并定义静态方法,导入
.popen_fork的Popen,这是关键293-295行代码,创建ForkContext类,并将ForkProcess类赋给类变量Process
208-321行代码,定义
_concrete_contexts变量,dict类型,将ForkContext类对象作为value放入,对应的key是fork313行代码(关键),创建DefaultContext类对象,并传入ForkContext类对象,定义
_default_context变量,指向上面的对象
查看process.BaseProcess类
由于Process类继承process.BaseProcess类,所以要看其父类的源代码
打开process.py文件,找到BaseProcess类,
run()方法
找到run()方法,执行传进来的target函数
start()方法
105行,调用_Popen(self)方法,这是关键,由于Process子类已经定义类静态方法_Popen(),所以这里调用的是Process的_Popen()方法
调用Process类的_Popen方法
该方法只有一行代码,如下:
return _default_context.get_context().Process._Popen(process_obj)
由上面可知,_default_context就是DefaultContext类对象,即调用该对象的get_context()方法,
查看该方法的定义,232-238行代码,即返回SpawnContext()类对象,
通过326行代码可知,Process是SpawnProcess类
通过320-322行代码可知,调用SpawnProcess类的静态方法_Popen,该方法返回当前包路径的popen_spawn_win32文件的Popen对象
查看popen_spawn_win32文件
打开popen_spawn_win32文件,定义Popen类,在46行,有代码_winapi.CreateProcess(),这里调用了python底层库_winapi,该库是针对windows系统api的封装,CreateProcess()是windows系统api,用于创建进程
查看popen_fork文件
同理打开popen_fork文件,在66行代码有os.fork(),os是python的模块,fork()函数是在UNIX、linux、MacOS系统中创建进程的
总结
也就是说,python在multiprocessing模块中,做了判断,如果是windows系统,调用windows创建进程的函数,如果是其他系统,调用os.fork()函数,
如下图:

