一、Process的join的用法
阻塞住主进程再等待子进程结束,然后再往下执行,(了解的是:内部会待用wait())。
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() p.join() print('主')
#并行 if __name__ == '__main__': p1 = Process(target=foo,args=(1,)) p2 = Process(target=foo,args=(2,)) p3 = Process(target=foo,args=(3,)) start = time.time() p1.start() # p2.start() # p3.start() # # 核心需求就是 # time.sleep(5) p3.join() #1s p1.join() #1s p2.join() #1s # 总时长:按照最长的时间计算多一点。 end = time.time() print(end-start) #3s多 or 6s多 ? 正解:3s多 print('主') 进程 start 进程 start 进程 start 进程 end 进程 end 进程 end 3.213395118713379 主
#串行 from multiprocessing import Process import time def foo(x): print(f'进程{x} start ') time.sleep(x) print(f'进程{x} end ') if __name__ == '__main__': p1 = Process(target=foo,args=(1,)) p2 = Process(target=foo,args=(2,)) p3 = Process(target=foo,args=(3,)) start = time.time() p1.start() p1.join() p2.start() p2.join() p3.start() p3.join() end = time.time() print(end-start) print('主') 进程1 start 进程1 end 进程2 start 进程2 end 进程3 start 进程3 end 6.465020179748535 主
#优化并行 from multiprocessing import Process 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) print('主')
二、Process的pid
from multiprocessing import Process,current_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('主') ''' os.getpid()#获取当前进程的pid os.getppid() #获取当前进程的父进程的pid 子进程对象.pid #获取当前进程的子进程pid ''' 在主进程查看子进程的pid 4676 主进程的pid 3936 主进程的父进程pid 12208 主 子进程 start 在子进程中查看自己的pid 4676 在子进程中查看父进程的pid 3936
三、Process的name和is_alive
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('主') True 进程 start --------------------- Process-1 进程 start --------------------- Process-2 进程 start --------------------- rocky 进程 end 进程 end 进程 end False Process-1 Process-2 rocky 主
关闭进程,不会立即关闭,所以is_alive立刻查看的结果可能还是存活。
name属性是Process中的属性,标示进程的名字。执行父类的初始化方法会覆盖name属性。self.name = person 可以修改进程名字,self.person = person 不覆盖进程名,修改属性名称也可以修改名称。
四、Process的terminal
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('主') True False 主
terminal关闭进程,不会立即关闭,所以is_alive立刻查看的结果可能还是存活。
五、守护进程
主进程创建守护进程,守护进程会在主进程代码执行结束后就终止,守护进程内无法再开启子进程,否则抛出异常。
注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止
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('主') 守护进程 start 主
from multiprocessing import Process import time def foo(): print('守护进程 start') time.sleep(3) print('守护进程 end') def task(): print('子进程 start') time.sleep(5) print('子进程 end') if __name__ == '__main__': p = Process(target=foo) p2 = Process(target=task) p.daemon = True # 把这个子进程定义为了守护进程 p.start() p2.start() time.sleep(1) print('主') 守护进程 start 子进程 start 主 子进程 end