直接上代码:
import time,os
from multiprocessing import Process # 导入模块
def func():
time.sleep(1)
print('hello',os.getpid()) # os.getpid()的作用是打印进程id
if __name__ == '__main__':
Process(target=func).start() # 开启了一个新的进程,然后在这个新的进程里执行了func中的代码
time.sleep(1)
print('hello2',os.getpid()) # 打印进程id
执行结果:
hello2 18448
hello 1972
这就开启了一个进程,可以通过进程id来进行测试,两个进程id不一样说明是同时有两个进程在工作,实现了异步的效果。
这里有几个概念:
父进程:父进程执行的过程中创建了子进程。例如pycharm作为一个进程,在pycharm里启动的进程就是子进程,此时pycharm就是父进程
子进程:与父进程是相对的
主进程:一般我们直接执行的那个程序就是主进程。
这里有几个问题:
①为什么一定要加if__name__ == __main__:这句?
如果mac和linux系统没有这句话仍然不会报错,这个是因为不同的操作系统启动进程的方式不同
windows开启一个子进程的方式:由于进程间数据隔离,所以理论上讲子进程无法应用父进程的数据,也无法运行父进程中的任何代码是import父进程所在的文件,所以通过import父进程所在的文件的方式加载一遍父进程的所有数据,所以如果不加这句话的话,开启的子进程中也会执行Process(target=func).star()
那么就会一直开子进程直到系统受不了。这很违背我们的本意,所以通过主进程中加入if __main__ == __name__:来控制主进程只开启一个子进程;
linux和mac系统是通过copy父进程的内存解决这个问题,也就是说会把Process(target=func).start()之前的内存copy到子进程中。这个时候要运行func(),因为内存中已经有了func()所以直接运行就OK了
总结:有与操作系统不同,导致开启子进程的方式有__main__的区别,莫慌,见到这样的错误,加上if __main__ == __name__:即可。
②如何开启多个子进程?(不信可通过os.getpid()证明一下,我信了所以不写)
if __main__ == __name__:
for i in range(10):
Process(target=func).start()
开子进程也可以这样写:
if __main__ == __name__:
for i in range(10):
p = Process(target=func) # 通过Process类实例化一个对象p
p.start() # 开启进程
③如何给子进程传参?
我们说各进程之间数据隔离,那么如何传参呢?
def func(name):
print('hello',name)
if __name__ == __main__:
p = Process(target=func,args=('carrie')) # 通过args传入一个元组,target对应的函数有几个参数就放到这个元组里
p.start() # start是非阻塞的 如果开启多个子进程的话 并非是挨个的开启 而是对操作系统说:请帮我开启n个子进程,
#然后就去干自己该干的事情了。所以操作系统什么时候开,先开谁后开谁都不管。
④子进程可以有返回值么?
理论上来讲子进程不应该有返回值,因为内存隔离的问题,子进程中的函数的返回值无法传给父进程
霸特,IPC机制,通过进程间通信机制可以把返回值返回给主进程