2019.09.12学习整理
孤儿进程
# 孤儿进程(无害) *
# 一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
'''
情况1 无害
父进等着子进程都死,回收僵尸进程。
情况2 无害
父进程死了,子进程活着,都要被init进程接管并且回收。
情况3
父进程一直不死,造成了大量僵尸进程。占用了大量的pid号
Procces的join用法
方式一
from multiprocessing import Process
import time
def foo():
print('进程 start ')
time.sleep(2.3)
print('进程 end ')
if __name__ == '__main__':
p = Process(target=foo)
p.start() #
# 核心需求就是
# time.sleep(5)
p.join() # 阻塞住主进程再等待子进程结束,然后再往下执行,(了解的是:内部会待用wait())
print('主')
方式二
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() #
# 核心需求就是
# time.sleep(5)
p3.join() #1s
p1.join() #1s
p2.join() #1s
# 总时长:按照最长的时间计算多一点。
end = time.time()
print(end-start) #3s多 or 6s多 ? 正解:3s多
print('主')
方式三
from multiprocessing import Process
import time
def foo(x):
print(f'进程{x} start ')
time.sleep(x)
print(f'进程{x} 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() #
p2.start() #
p2.join() #
p3.start() #
p3.join() #
# 不如不开,直接穿行调用函数反而快
# foo(1)
# foo(2)
# foo(3)
# 核心需求就是
# time.sleep(5)
# p3.join() #1s
# p1.join() #1s
# p2.join() #1s
# 总时长:按照最长的时间计算多一点。
end = time.time()
print(end-start) #3s多 or 6s多 ? 正解:3s多
print('主')
方式四
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)
print(p_list)
for p in p_list:
p.join()
end = time.time()
print(end-start) #3s多 or 6s多 ? 正解:3s多
print('主')
Process的pid用法
pid号是有限的。
解决方案:
最直接的办法就是杀死父进程 。
from multiprocessing import Process,current_process
import time,os
def task():
print('子进程 start')
print('在子进程中查看自己的pid',current_process().pid) # 在子进程中查看自己的pid
print('在子进程中查看父进程的pid',os.getppid()) #
time.sleep(200)
print('子进程 end')
if __name__ == '__main__':
p = Process(target=task)
p.start()
print('在主进程查看子进程的pid',p.pid) # 一定要写在 start()之后
print('主进程的pid',os.getpid())
print('主进程的父进程pid',os.getppid())
print('主')
'''
# 记住这些就ok了 这个是要掌握的
# 角度 站在当前进程的角度
os.getpid()#获取当前进程的pid
os.getppid() #获取当前进程的父进程的pid
子进程对象.pid #获取当前进程的子进程pid
'''
守护进程
方式一
'''
守护进程
守护--》伴随
本质也是一个子进程
主进程的代码执行完毕守护进程直接结束。但是此时主进程可能没有结束.
'''
from multiprocessing import Process
import time
def foo():
print('守护进程 start')
time.sleep(5)
print('守护进程 end')
if __name__ == '__main__':
p = Process(target=foo)
p.daemon = True # 把这个子进程定义为了守护进程
p.start()
time.sleep(2)
print('主')
方式二
'''
守护进程
守护--》伴随
本质也是一个子进程
主进程的代码执行完毕守护进程直接结束。
'''
from multiprocessing import Process
import time
def foo():
print('守护进程 start')
time.sleep(3)
print('守护进程 end')
def task():
print('子进程 start')
time.sleep(5)
print('子进程 end')
if __name__ == '__main__':
p = Process(target=foo)
p2 = Process(target=task)
p.daemon = True # 把这个子进程定义为了守护进程
p.start()
p2.start()
time.sleep(1)
print('主')
抢票小程序
from multiprocessing import Process
import json,time,os
def search():
time.sleep(1) # 模拟网络io
with open('db.txt',mode='rt',encoding='utf-8') as f:
res = json.load(f)
print(f'还剩{res["count"]}')
def get():
with open('db.txt',mode='rt',encoding='utf-8') as f:
res = json.load(f)
# print(f'还剩{res["count"]}')
time.sleep(1) # 模拟网络io
if res['count'] > 0:
res['count'] -= 1
with open('db.txt',mode='wt',encoding='utf-8') as f:
json.dump(res,f)
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()
# 为了保证数据的安全,要牺牲掉效率.