目录
- Process的几个用法和守护进程
- 一、Process的 join用法
- 二、Process的pid和ppid用法
- 四、Process的is_alive的用法
- 五、Process的terminate用法
- 六、守护进程
- 七、抢票小程序
Process的几个用法和守护进程
一、Process的 join用法
话不多说,直接上代码
join 用法一 ,单进程
from multiprocessing import Process
import time
def foo():
print('子进程 start')
time.sleep(2)
print('子进程 end')
if __name__ == '__main__':
p = Process(target=foo)
p.start()
# 核心需求就是想让子进程执行完,再执行主进程的print,time有弊端
# time.sleep(5)
p.join() # 在这阻塞住,主进程等待该子进程结束,然后再往下执行,(了解:内部会调用wait())
print('主进程')
# join用法二(并发)
from multiprocessing import Process
import time
def foo(x):
print('子进程 start')
time.sleep(x)
print('子进程 end')
if __name__ == '__main__':
p1 = Process(target=foo,args=(1,))
p2 = Process(target=foo,args=(2,))
p3 = Process(target=foo,args=(3,))
start = time.time()
p1.start()
p2.start()
p3.start() # 这几个相当于并发
# 核心需求就是想让子进程执行完,再执行主进程的print,time有弊端
# time.sleep(5)
p1.join() # 在这阻塞住,主进程等待该子进程结束,然后再往下执行,(了解:内部会调用wait())
p2.join()
p3.join()
# 总时长:按照最长的时间计算多一点
end = time.time()
print(end-start)
print('主进程')
# join用法三(串行)
from multiprocessing import Process
import time
def foo(x):
print('子进程 start')
time.sleep(x)
print('子进程 end')
if __name__ == '__main__':
p1 = Process(target=foo,args=(1,))
p2 = Process(target=foo,args=(2,))
p3 = Process(target=foo,args=(3,))
start = time.time()
p1.start()
p1.join() # 在这阻塞住,主进程等待该子进程结束,然后再往下执行,(了解:内部会调用wait())
p2.start()
p2.join()
p3.start() # 这几个相当于并行
p3.join()
# 核心需求就是想让子进程执行完,再执行主进程的print,time有弊端
# time.sleep(5)
# 总时长:按照最长的时间计算多一点
end = time.time()
print(end-start)
print('主进程')
# 优化join用法二
from multiprocessing import Process
import time
def foo(x):
print(f'子进程{x} start')
time.sleep(x)
print(f'子进程{x} end')
if __name__ == '__main__':
start = time.time()
p_list = []
for i in range(1,4):
p = Process(target=foo, args=(i,))
p.start()
p_list.append(p)
for p in p_list:
p.join()
end = time.time()
print(end-start)
print('主进程')
二、Process的pid和ppid用法
需要先导入os模块
站在当前进程的角度:os.getpid()>>>>获取当前进程的pid
? os.getppid()>>>>获取当前进程的父进程的pid
? 子进程对象.pid>>>>获取当前进程的子进程pid
具体看以下代码
from multiprocessing import Process,current_process
import time,os
def task():
print('子进程 start')
print('在子进程中查看自己的pid',current_process().pid) # 在子进程查看自己pid方法一
print('在子进程中查看自己的pid',os.getpid()) # 在子进程查看自己pid方法二
print('在子进程中查看父进程的pid',os.getppid())
time.sleep(2)
print('子进程 end')
if __name__ == '__main__':
p = Process(target=task)
p.start()
print('在主进程查看子进程的pid',p.pid) # 获取pid,一定要写在start()之后
print('主进程的pid',os.getpid())
print('主进程的父进程pid',os.getppid())
print('主进程')
在主进程查看子进程的pid 1928
主进程的pid 2900
主进程的父进程pid 1008
主进程
子进程 start
在子进程中查看自己的pid 1928
在子进程中查看自己的pid 1928
在子进程中查看父进程的pid 2900
子进程 end
三、Process的name用法
这是用来查看进程名的
from multiprocessing import Process,current_process
import time
def foo():
print('子进程 start')
print('>>>>',current_process().name) # 获取当前进程名
time.sleep(2)
print('子进程 end')
if __name__ == '__main__':
p = Process(target=foo)
p.start()
print(p.name)
Process-1
子进程 start
Process-1
子进程 end
四、Process的is_alive的用法
用来判断进程是否活着,结果是True或False
from multiprocessing import Process,current_process
import time
def foo():
print('子进程 start')
time.sleep(2)
print('子进程 end')
if __name__ == '__main__':
p = Process(target=foo)
p.start()
print(p.is_alive()) # 没运行完就活着 True
time.sleep(5)
print(p.is_alive()) # 代码运行完了就算死了 False
print('主进程')
True
子进程 start
子进程 end
False
主进程
五、Process的terminate用法
用来直接把进程终止(死掉)
from multiprocessing import Process,current_process
import time
def foo():
print('子进程 start')
time.sleep(50)
print('子进程 end')
if __name__ == '__main__':
p = Process(target=foo)
p.start()
p.terminate() # 给操作系统发了一个终止进程的请求
print(p.is_alive()) # 没运行完就活着 True
p.join() # 可以不等50秒,直接执行下面的
print(p.is_alive())
print('主进程')
True
False
主进程
六、守护进程
守护进程本质也是一个子进程,主进程的代码执行完毕,守护进程就直接结束
from multiprocessing import Process
import time
def foo():
print('守护进程 start')
time.sleep(10)
print('守护进程 end')
if __name__ == '__main__':
p = Process(target=foo)
p.daemon = True # 把这个子进程定义为了守护进程,只陪伴到打印主进程就结束
p.start()
print('主进程') # 这个执行完,主进程的代码就执行完毕,子进程就直接结束,
主进程
七、抢票小程序
from multiprocessing import Process
import json,time,os
def search():
time.sleep(1)
with open('db',mode='rt',encoding='utf-8') as fr:
res = json.load(fr)
print(f'还剩{res["count"]}张')
def get():
with open('db',mode='rt',encoding='utf-8') as fr:
res = json.load(fr)
time.sleep(1) # 模拟网络io
if res['count'] > 0:
res['count'] -= 1
with open('db',mode='wt',encoding='utf-8') as fw:
json.dump(res,fw)
time.sleep(1.5) # 模拟网络io
print(f'进程{os.getpid()}抢票成功')
else:
print('票已售罄!!!')
def task():
search()
get()
if __name__ == '__main__':
for i in range(15):
p = Process(target=task)
p.start()
p.join()
# 为了保证数据的安全,要牺牲掉效率
Process的几个用法和守护进程