如果我们有两个任务需要并发执行,那么我们需要开一个主进程和一个子进程去执行,如果子进程的任务在主进程执行完成后没有存在的必要了,那么该子进程应该在开启前就被设置成守护进程。主进程代码运行结束,守护进程随之终止。
# 守护进程daemon
from multiprocessing import Process
import time
def task(name):
print('%s is running'%name)
time.sleep(2)
print('%s is done'%name)
if __name__ == '__main__':
p = Process(target=task,args=('子进程',))
p.daemon = True # 设置为守护进程
p.start()
print('主进程......')
验证守护进程内无法再开启子进程
from multiprocessing import Process
import time
def task(name):
print('%s is running'%name)
time.sleep(2)
print('%s is done'%name)
p1 = Process(target=time.sleep,args=(3,))
p1.start()
if __name__ == '__main__':
p = Process(target=task,args=('子进程',))
p.daemon = True
p.start()
p.join() # 因为是验证无法再开启子进程,所以需要在添加前能保证子进程的程序能运行完
print('主进程......')
# 那么运行结果是:反正就是一堆的报错
子进程 is running
Process Process-1:
子进程 is done
Traceback (most recent call last):
File "D:\python\python3\lib\multiprocessing\process.py", line 258, in _bootstrap
self.run()
File "D:\python\python3\lib\multiprocessing\process.py", line 93, in run
self._target(*self._args, **self._kwargs)
File "D:\py_study\day22-多线程开始\test.py", line 16, in task
p1.start()
File "D:\python\python3\lib\multiprocessing\process.py", line 103, in start
'daemonic processes are not allowed to have children'
AssertionError: daemonic processes are not allowed to have children
主进程......
互斥锁
进程之间的数据是不共享的,但是共享同一套文件系统,所以访问同一个文件,或者同一个打印终端,是没有问题的,而共享带来的就是竞争,竞争带来的就是错乱,如下:
# 并发执行,效率高,但竞争着同一个打印终端,所以会带来错乱
from multiprocessing import Process
import time,os
def task():
print('%s is running'%os.getpid())
time.sleep(2)
print('%s is done.'%os.getpid())
if __name__ == '__main__':
for i in range(5):
p = Process(target=task)
p.start()
# 运行结果为:
13580 is running
7912 is running
6176 is running
13668 is running
12172 is running
7912 is done.
13580 is done.
6176 is done.
13668 is done.
12172 is done.
如何控制,就是加锁处理。而互斥锁的意思就是相互排斥,如果把多个进程比喻成多个人,那么互斥锁的工作原理就是多个人都要去争抢同一个资源:洗手间,一个人抢到了洗手间的锁,其余的人就要都等着,等到这个任务执行完成后释放锁,其他人中的一个人才有可能抢到这把锁......所以互斥锁的原理就是:把并行改为串行,降低了效率,但是保证了数据的安全不错乱。
from multiprocessing import Process,Lock
import time,os
def task(Lock):
Lock.acquire() # 加锁
print('%s is running'%os.getpid())
time.sleep(2)
print('%s is done.'%os.getpid())
Lock.release() # 释放锁
if __name__ == '__main__':
lock = Lock() # 先实例化一个对象
for i in range(5):
p = Process(target=task,args=(lock,))
p.start()
# 运行结果为
13868 is running # 一个子进程开始了
13868 is done. # 这个子进程死掉了
9576 is running
9576 is done.
13956 is running
13956 is done.
11696 is running
11696 is done.
11632 is running
11632 is done.
我们接下来举一个抢票的例子大家可能就懂了
模拟抢票
我们在12306上抢票过程中,明明看到了仅剩下1张票,但是现在呢有10个人在开始抢票,让我们来模拟一下:
from multiprocessing import Process
import json
import time