一. multiprocess模块
仔细说来,multiprocess不是一个模块而是python中一个操作、管理进程的包。 之所以叫multi是取自multiple的多功能的意思,在这个包中几乎包含了和进程有关的所有子模块。由于提供的子模块非常多,为了方便大家归类记忆,我将这部分大致分为四个部分:创建进程部分,进程同步部分,进程池部分,进程之间数据共享。
process模块介绍
process模块是一个创建进程的模块,借助这个模块,就可以完成进程的创建。
二. 使用process模块创建进程
1.第一种:
import os from multiprocessing import Process def func(*args): print(args) print(‘子进程‘,os.getpid()) print(‘子进程的父进程‘,os.getppid()) if __name__ == ‘__main__‘: p = Process(target=func,args=(‘参数1‘,‘参数2‘)) p.start() p.join() # 感知一个子进程的结束,将异步的程序改为同步 print(‘主进程‘, os.getpid()) print(‘主进程的父进程‘, os.getppid())
2. 第二种
import os from multiprocessing import Process class MyProcess(Process): def __init__(self,args1,args2): super().__init__() # Process.__init__(self) self.args1 = args1 self.args2 = args2 def run(self): print(111) print(self.args1) print(self.args2) print(self.pid) if __name__ == ‘__main__‘: p = MyProcess(‘参数1‘,‘参数2‘) p.start() print(os.getpid())
创建多个子进程
import os from multiprocessing import Process def func(filename,count): with open(filename,‘w‘,encoding=‘utf-8‘) as f: f.write(count*10*‘*‘) if __name__ == ‘__main__‘: p_list = [] for i in range(10): p = Process(target=func,args=(‘userinfo%d‘%i,i)) p_list.append(p) p.start() [p.join() for p in p_list] print([i for i in os.walk(r‘e:\python10\day37‘)])
三. 进程之间的数据隔离问题
import os import time from multiprocessing import Process def func(): global n n = 0 print(‘pid:%s‘%os.getpid(),n) if __name__ == ‘__main__‘: n = 100 p= Process(target=func) p.start() p.join() print(n)
四. 守护进程
import os import time from multiprocessing import Process def func(): while True: print(‘子进程开始‘) time.sleep(1) print(‘***我还在运行‘) if __name__ == ‘__main__‘: p = Process(target=func) p.daemon = True p.start() p1 = Process(target=func) p1.start() p1.terminate() print(p1.is_alive()) time.sleep(5) print(p1.is_alive())
五. 锁 —— multiprocess.Lock
加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行的修改,没错,速度是慢了,但牺牲了速度却保证了数据安全。
虽然可以用文件共享数据实现进程间通信,但问题是:
1.效率低(共享数据基于文件,而文件是硬盘上的数据)
2.需要自己加锁处理
因此我们最好找寻一种解决方案能够兼顾:
1、效率高(多个进程共享一块内存的数据)
2、帮我们处理好锁问题。这就是mutiprocessing模块为我们提供的基于消息的IPC通信机制:队列和管道。 队列和管道都是将数据存放于
内存中 队列又是基于(管道+锁)实现的,可以让我们从复杂的锁问题中解脱出来, 我们应该尽量避免使用共享数据,尽可能使用消息传递
和队列,避免处理复杂的同步和锁问题,而且在进程数目增多时,往往可以获得更好的可获展性。
import time import json from multiprocessing import Process from multiprocessing import Lock def show_ticket(i): with open(‘ticket‘) as f: dic = json.load(f) print(‘余票:%s‘%dic[‘ticket‘]) def buy_ticket(i,lock): lock.acquire() with open(‘ticket‘) as f: dic = json.load(f) print(‘余票:%s‘ % dic[‘ticket‘]) time.sleep(0.1) if dic[‘ticket‘] > 0: dic[‘ticket‘] -= 1 print(‘\033[32m%s买到票了\033[0m‘%i) else: print(‘\033[31m%s买到票了\033[0m‘%i) time.sleep(0.1) with open(‘ticket‘,‘w‘) as f: json.dump(dic,f) lock.release() if __name__ == ‘__main__‘: for i in range(10): p = Process(target=show_ticket,args=(i,)) p.start() lock = Lock() for j in range(10): p = Process(target=buy_ticket,args=(j,lock)) p.start()