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("主进程:没有人在唱歌了")