昨日回顾
操作系统发展史
串行:一个完完整整执行完在执行别的
并发:看起来同时运行,单核中发生
并行:真正的同时运行
多道技术:
空间复用:多个进程互相隔离,物理级别的隔离
时间复用:公用一个cpu
程序:硬盘中的代码
进程:一个正在执行的程序,是一系列资源的综合
开启子进程
开子进程 申请新的内存空间 把父进程的所有代码完整拷贝一份过去
from multiprocessing import Process
def task(x):
pass
if name == 'main':
p = Process(target=task,args=(45,))
p.start()
第二种开启子进程的方式不常用
from multiprocessing import Process
class Xx(Process):
def init(self,x):
super().init()
self.x = x
def run(self):
pass
p = Xx()
p.start()
尽量减少阻塞状态可以提高程序运行的效率
并发 = 保存状态+切换
僵尸进程孤儿进程
僵尸进程与孤儿进程
僵尸进程:父进程的子进程结束的时候父进程没有wait()情况下回变成僵尸进程
父进程等着所有子进程结束才会结束
孤儿进程:一个父进程退出,他的子进程还在运行,这些就成了孤儿进程,会被
init进程收养,并有init进程完成状态手机工作
情况一:无害
父进程等着子进程都死,回收僵尸进程
情况二:无害
父进程死了,子进程还活着,都要被init进程接管回收
情况三:有害
父进程一直不死,造成大量僵尸进程,占用大量pid好
pid 号是有限的,解决方案:直接杀死子进程
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()
# time.sleep(5)
p.join() # 阻塞住进程在等待子进程结束,然后往下执行(其实内部会使用wait())
# 主进程在等待该子进程结束,sleep无法准确设置,相当于稳定的time.sleep
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()
# p1.join() 串行
p2.start()
# p2.join()
p3.start()
# # p3.join()
# p1.join() 并发
# p2.join()
# p3.join()
end = time.time()
print(end-start)
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(type(p))
print(p_list )
for p in p_list:
p.join()
end = time.time()
print(end-start)
print('结束')
pid,ppid的查看方式
from multiprocessing import Process,current_process
# current_process 获取
import time,os
def task():
# print('asdfg')
print('start')
print(current_process().pid) # 在子进程中自己查看自己的pid
# print(os.getpid()) # 在子进程中查看自己的pid
print(os.getppid()) # 在子进程查看父进程的pid
time.sleep(100)
print('end')
if __name__ == '__main__':
p = Process(target=task)
p.start()
print(p.pid) # 在主进程查看子进程的pid
# 进程.pid有了返回,没有返回None,一定要写在start之后
print(os.getpid()) # 主进程的pid
print(os.getppid()) # 主进程的父进程、pycharm
'''
当前进程下:
os.getpid(),当前进程的pid
os.getppid(),当前进程的父进程的pid
子进程对象.pid 当前进程的子进程pid
'''
Process的其他用法
Process的其他用法
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)
# p2 = Process(target=foo)
# p3 = Process(target=foo,name='qxp') # name,自定义进程名字
p.start()
p.terminate() # 给操作系统发请求,强制结束子进程
p.join()
print(p.is_alive()) # 判断是否存活
# p2.start()
# p3.start()
# print(p.name)
# print(p2.name)
# print(p3.name)
守护进程
守护进程,在主进程代码结束后会终止
守护---伴随
主进程代码执行完毕后守护进程结束,本质也是子进程
from multiprocessing import Process
import time
def foo():
print('守护进程')
if __name__ == '__main__':
p = Process(target=foo)
p.daemon = True # 把它定义为守护进程
p.start()
print('zhu')