孤儿进程(亚索进程)
我们上次讲了僵尸进程,今天就来讲讲孤儿进程。
所谓孤儿,就是亚索,没爹的东西。
就是一个子进程的父进程挂掉的时候,这个子进程就会成为一个孤鹅,他将会被一个叫做init的进程收养,然后被人道毁灭。说到底,孤鹅进程是没啥关系的,不像僵尸进程,死又死不掉,又占着茅坑不拉屎,最后导致进程号都不够用了。
一共有三种情况:
情况1 无害父进等着子进程都死,回收僵尸进程。
情况2 无害父进程死了,子进程活着,都要被init进程接管并且回收。
情况3父进程一直不死,造成了大量僵尸进程。占用了大量的pid号
解决方案是什么,最直接的办法就是直接把他们的爸爸杀了,只要他们的父进程死了,无论怎么样,这些子进程最后都会挂掉!
Process的join用法
from multiprocessing import Process import time def foo(): print('进程 start ') time.sleep(2.3) print('进程 end ') if __name__ == '__main__': p = Process(target=foo) p.start() # # 核心需求就是 # time.sleep(5) p.join() # 阻塞住主进程再等待子进程结束,然后再往下执行,(了解的是:内部会待用wait()) print('主')
join方法的用处就是阻塞住主进程等子进程结束了再往下走。
优化版:
import time def foo(x): print(f'进程{x} start ') time.sleep(x) print(f'进程{x} end ') if __name__ == '__main__': start = time.time() p_list = [] for i in range(1,4): p = Process(target=foo,args=(i,)) p.start() p_list.append(p) print(p_list) for p in p_list: p.join() end = time.time() print(end-start) #3s多 or 6s多 ? 正解:3s多 print('主')
结果是三秒多。自己体会,才是最有味的,主要是我不想解释了
因为在你join之前,每一个子进程都已经start了,所以只用等最后一个结束就好了。
Process的其他用法
import time,os def task(): print('子进程 start') print('在子进程中查看自己的pid',current_process().pid) # 在子进程中查看自己的pid print('在子进程中查看父进程的pid',os.getppid()) # time.sleep(200) print('子进程 end') if __name__ == '__main__': p = Process(target=task) p.start() print('在主进程查看子进程的pid',p.pid) # 一定要写在 start()之后 print('主进程的pid',os.getpid()) print('主进程的父进程pid',os.getppid()) print('主')
过目就好
from multiprocessing import Process,current_process import time def foo(): print('进程 start') # print('--------------------- ',current_process().name) time.sleep(2) print('进程 end') if __name__ == '__main__': p = Process(target=foo) # p2 = Process(target=foo) # p3 = Process(target=foo,name='rocky') p.start() # p2.start() # p3.start() print(p.is_alive()) # True time.sleep(5) print(p.is_alive()) # 代码运行完了就算死了 False # print(p.name) # print(p2.name) # print(p3.name) print('主')
仅作了解
from multiprocessing import Process,current_process import time def foo(): print('进程 start') # print('--------------------- ',current_process().name) time.sleep(50) print('进程 end') if __name__ == '__main__': p = Process(target=foo) p.start() p.terminate() # 给操作系统发了一个请求 print(p.is_alive()) # True p.join() print(p.is_alive()) # False print('主')
terminate方法是给操作系统下一个请求,直接结束进程的作用,谁调用,就结束谁。
守护进程
''' 守护进程 守护--》伴随 本质也是一个子进程 主进程的代码执行完毕守护进程直接结束。但是此时主进程可能没有结束. ''' from multiprocessing import Process import time def foo(): print('守护进程 start') time.sleep(5) print('守护进程 end') if __name__ == '__main__': p = Process(target=foo) p.daemon = True # 把这个子进程定义为了守护进程 p.start() time.sleep(2) print('主')
我感觉不到守护进程的作用,但是具体应用场景我们还没接触到,可能就是有这么一个业务需求,需要用守护进程来实现。听起来很牛逼的东西,其实就是你死,我也死。