multiprocess模块
仔细说来,multiprocess不是一个模块而是python中一个操作、管理进程的包。 之所以叫multi是取自multiple的多功能的意思,在这个包中几乎包含了和进程有关的所有子模块。由于提供的子模块非常多,为了方便大家归类记忆,我将这部分大致分为四个部分:创建进程部分,进程同步部分,进程池部分,进程之间数据共享。
import os import time from multiprocessing import Process def func(args1,args2): print(args1,args2) time.sleep(3) print("子进程:",os.getpid()) print("子进程的父进程:",os.getppid()) print(12345) if __name__ == "__main__": p=Process(target=func,args=("参数1","参数2")) #注册 一个进程对象 p.start()#开启了一个子进程 print("##############") print("父进程:",os.getpid())#查看当前进程的进程号 print("父进程的父进程:",os.getppid()) #当start()执行完毕,就开始同时执行子进程函数中的代码和父进程中start之后的代码(多进程)
join()
将异步的程序改为同步
def func(arg1,arg2): print("*"*arg1) time.sleep(5) print("#"*arg2) if __name__ == "__main__": p=Process(target=func,args=(10,20)) p.start() print("哈哈哈") # p.join() print("-----运行完毕------") """ 输出: 哈哈哈 ********** #################### -----运行完毕------ 如果没有join()则 输出: 哈哈哈 -----运行完毕------ ********** #################### """
开启多个子进程:
def func(arg1,arg2): print(arg1*"a") time.sleep(5) print(arg2*"b") if __name__=="__main__": p_list=[] for i in range(5): p=Process(target=func,args=(2*i,3*i)) p.start() p_list.append(p) #把所有的p对象,按顺序放在一个列表 [p.join() for p in p_list] #join每个p 就是检测是否执行完,执行结束在继续走 print("结束")
开启多进程的第二种方法:
自定义类 继承Process类
必须实现一个run方法,run方法中是在子进程中执行的代码
from multiprocessing import Process class MyProcess(Process): def run(self): print(os.getpid()) if __name__ == "__main__": print("主进程:", os.getpid()) p=MyProcess() p.start()
有参数的:
from multiprocessing import Process class MyProcess(Process): def __init__(self,arg1,arg2): super().__init__() #缺少必要的属性,需要在父类中用super继承 self.arg1=arg1 self.arg2=arg2 def run(self): print("参数1",self.arg1) print("参数2",self.arg2) print(self.name) #内置属性 调进程名 print(self.pid) #内置属性 调进程号 print(os.getpid()) #和上面的进程号是同一个,哪种方法都可以 if __name__ == "__main__": print("主进程:", os.getpid()) p=MyProcess(123,456) p.start()
多进程间的数据隔离问题:
多个进程之间的所有数据都是隔离的
使用多进程实现socket服务端的并发效果:
import socket from multiprocessing import Process def serve(conn): ret = '你好'.encode('utf-8') conn.send(ret) msg = conn.recv(1024).decode('utf-8') print(msg) conn.close() if __name__ == '__main__' : sk = socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen() try: while True: conn,addr = sk.accept() p = Process(target=serve,args=(conn,)) p.start() finally: sk.close()
import socket sk = socket.socket() sk.connect(('127.0.0.1',8080)) msg = sk.recv(1024).decode('utf-8') print(msg) msg2 = input('>>>').encode('utf-8') sk.send(msg2) sk.close()
守护进程:
会随着主进程的结束而结束。
主进程创建守护进程
其一:守护进程会在主进程代码执行结束后就终止
其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes are not allowed to have children
注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止
p.terminate() 在主进程内结束一个子进程
p.is_alive() 检验一个进程是否在运行状态
p.daemon=True 表示新的子进程是一个守护进程(一定在start之前设置)
import time from multiprocessing import Process def func(): while True: time.sleep(0.2) print('我还活着') def func2(): print('in func2 start') time.sleep(8) print('in func2 finished') if __name__ == '__main__': p = Process(target=func) p.daemon = True # 设置子进程为守护进程 p.start() p2 = Process(target=func2) p2.start() p2.terminate() # 结束一个子进程 time.sleep(1) print(p2.is_alive()) # 检验一个进程是否还活着 print(p2.name)