在学习python进程相关知识的时候,查询各种网站或者博客,对于进程的解释都没有那么全面,有时候仅给出部分案例,导致代码有时候爆出一些莫名其妙的错误,因此写下这篇基础文章。

python 的三种进程模式

在python当中进程被分为三种模式,不同的模式有不同的约束条件,也有不同的运行场景,需要依据情况而定:

fork spawn forkserver
拷贝几乎程序拥有的所有资源 需要从启动函数处传入程序运行的必要资源 需要从启动函数处传入程序运行的必要资源
支持文件对象/线程锁等传参 不支持文件对象/线程锁等传参 不支持文件对象/线程锁等传参
unix unix/win 部分unix
任意位置创建 main函数开始 main函数开始

注:main函数指:

1
2
>if __name__ == "__main__":
pass

并非指代函数名为main函数的函数。

案例

fork

1
2
3
4
5
6
7
8
9
10
11
12
import multiprocessing


def task():
print(ele) # 不需要传参,创建进程的时候会拷贝资源

if __name__ == "__main__":
multiprocessing.set_start_method("fork")
ele = []

res = multiprocessing.Process(target=task)
res.start()

spawn

1
2
3
4
5
6
7
8
9
10
11
12
import multiprocessing


def task(ele):
print(ele) # 需要传参,否则会报错,但是不能传递文件对象/线程锁等

if __name__ == "__main__":
multiprocessing.set_start_method("spawn")
ele = []

res = multiprocessing.Process(target=task,args=(ele,))
res.start()

forkserver

1
2
3
4
5
6
7
8
9
10
11
12
import multiprocessing


def task(ele):
print(ele) # 需要传参,否则会报错,但是不能传递文件对象/线程锁等

if __name__ == "__main__":
multiprocessing.set_start_method("forkserver")
ele = []

res = multiprocessing.Process(target=task,args=(ele,))
res.start()

补充

进程创建的时候提到了mmain函数,这里补充一下什么是main函数,在程序运行的过程当中main函数扮演的什么角色。

__name__是个啥?

  • __name__是一个python的内置函数
  • __name__是python的一个内置类属性,它天生就存在于一个 python 程序中
  • 直接运行python程序时,__name__的值为"__main__"
  • 而在其它程序中导入.py文件运行时,__name__的值为文件名,即模块名

if __name__ == "__main__"的作用

最简单的情况:运行当前的module(Py文件)时,因为__name__为”main“,所以__main__下方的代码会被顺序执行到。除了这种情况,还有就是在B文件导入A文件的时候,if __name__ == "__main__"条件下的代码模块不会被一同导入执行。