1 进程的创建与结束
1.1 multiprocess.process模块
- process模块是一个创建进程的模块,借助这个模块,就可以完成进程的创建。
- 创建一个子进程
from multiprocessing import Process import time,os def func(): time.sleep(2) print("i am 子进程,pid %s" %(os.getpid())) if __name__ == "__main__": p = Process(target=func) p.start() print("i am 主进程,pid %s" %(os.getpid()))
- join方法的使用,主线程等待子线程终止
from multiprocessing import Process import time,os def func(): time.sleep(2) print("i am 子进程,pid %s" %(os.getpid())) if __name__ == "__main__": p = Process(target=func) p.start() p.join() print("i am 主进程,pid %s" %(os.getpid()))
- 同时开启多个子进程,并且执行完毕后在主进程
from multiprocessing import Process import time,os def func(): time.sleep(2) print("i am 子进程,pid %s" %(os.getpid())) if __name__ == "__main__": p_list=[] for i in range(4): p = Process(target=func) p.start() p_list.append(p) for p in p_list: p.join() time.sleep(1) print("i am 主进程,pid %s" %(os.getpid()))
- 进程与子进程数据是隔离的
from multiprocessing import Process import time,os n=100 def func(name): n=20 time.sleep(2) print("i am 子进程,pid %s,%s,%s" %(os.getpid(),name,n)) if __name__ == "__main__": p_list=[] for i in range(4): p = Process(target=func,args=(i,)) p.start() p_list.append(p) for p in p_list: p.join() time.sleep(1) print("i am 主进程,pid %s,%s" %(os.getpid(),n))
- 守护进程:会随着主进程的结束而结束。主进程创建守护进程
其一:守护进程会在主进程代码执行结束后就终止
其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes are not allowed to have children
注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止
from multiprocessing import Process import time,os def func(name): time.sleep(2) print("i am 子进程,pid %s,%s" %(os.getpid(),name)) if __name__ == "__main__": p = Process(target=func,args=('abc',)) p.daemon = True p.start() print("i am 主进程,pid %s" %(os.getpid()))
- 主进程代码执行结束守护进程立即结束
from multiprocessing import Process import time,os def func1(name): time.sleep(1) print("i am 子进程,pid %s,%s" %(os.getpid(),name)) def func2(name): time.sleep(2) print("i am 子进程,pid %s,%s" %(os.getpid(),name)) if __name__ == "__main__": p1 = Process(target=func1,args=('func1',)) p2 = Process(target=func2,args=('func2',)) p1.daemon = True #p1不会被打出 p1.start() p2.start() print("i am 主进程,pid %s" %(os.getpid()))
- 进程锁:当多个进程使用同一份数据资源的时候,就会引发数据安全或顺序混乱问题。
- 虽然使用加锁的形式实现了顺序的执行,但是程序又重新变成串行了,这样确实会浪费了时间,却保证了数据的安全
import os,time from multiprocessing import Process,Lock def fun1(i,lock): lock.acquire() time.sleep(1) print("%s,%s" %(os.getpid(),i)) lock.release() if __name__ == '__main__': lock=Lock() for i in range(3): p=Process(target=fun1,args=(i,lock)) p.start() print("i am 主进程 %s" %(os.getpid()))
- 模拟抢票需要用到进程锁
import os,time,json from multiprocessing import Process,Lock def rob_ticket(num,lock): lock.acquire() ticket_dic=json.load(open("db")) time.sleep(0.2) print("剩余的票数为%s" %ticket_dic["count"]) if ticket_dic["count"]>0: ticket_dic["count"]-=1 time.sleep(1) #模拟网络延迟 json.dump(ticket_dic,open("db","w")) print("%s抢票成功" %num) lock.release() if __name__=="__main__": lock=Lock() for num in range(5): p=Process(target=rob_ticket,args=(num,lock)) p.start()
- 信号量相当于有多把钥匙和锁
- 模拟KTV房间人进进出出,房间不是一个
#!/usr/bin/env python import time from multiprocessing import Semaphore,Process def go_ktv(sem,num): sem.acquire() print("%s现在在ktv唱歌"%num) time.sleep(1) sem.release() if __name__ == "__main__": sem=Semaphore(3) p_l=[] for i in range(10): p=Process(target=go_ktv,args=(sem,"User%s"%i)) p.start() p_l.append(p) for p in p_l: p.join() print("主进程:没有人在唱歌了")