Day35
今日总结
代码创建进程
创建进程的两种方式
1.运行应用程序
2.代码创建进程(在内存中申请一块内存空间运行相应的程序代码)
# 第一种方式
from multiprocessing import Process
import time
def task(name):
print('%s is running' % name)
time.sleep(3)
print('%s is over' % name)
if __name__ == '__main__':
p = Process(target=task, args=('QQ',)) # 创建进程对象
p.start() # 创建一个新的进程
# 第二种方式
from multiprocessing import Process
import time
class MyProcess(Process):
def __init__(self, username):
self.username = username
super().__init__()
def run(self):
print(f'{self.username} is running')
time.sleep(3)
print(f'{self.username} is over')
if __name__ == '__main__':
p = MyProcess('QQ')
p.start()
join方法
join可以让主进程等待子进程结束之后,再执行主进程
from multiprocessing import Process
import time
# 不使用join方法
def task(name):
print(f"{name} is running")
time.sleep(2)
print(f"{name} is gone")
if __name__ == "__main__":
p = Process(target=task, args=("QQ",)) # 创建一个进程对象
p.start()
# p.join()
print("主进程")
# 主进程
# QQ is running
# QQ is gone
# 使用join方法
def task(name):
print(f"{name} is running")
time.sleep(2)
print(f"{name} is gone")
if __name__ == "__main__":
p = Process(target=task, args=("QQ",)) # 创建一个进程对象
p.start()
p.join()
print("主进程")
# QQ is running
# QQ is gone
# 主进程
def task(name, n):
print(f'{name} is running')
time.sleep(n)
print(f'{name} is over')
if __name__ == '__main__':
p1 = Process(target=task, args=('jason', 1))
p2 = Process(target=task, args=('tony', 2))
p3 = Process(target=task, args=('kevin', 3))
start_time = time.time()
p1.start()
p2.start()
p3.start()
p1.join()
p2.join()
p3.join()
end_time = time.time() - start_time
print('主进程', f'总耗时:{end_time}') # 主进程 总耗时:3.015652894973755
# 如果是一个start一个join交替执行 那么总耗时就是6s+
进程间数据默认隔离
from multiprocessing import Process
money = 999
def task():
global money
money = 666
if __name__ == '__main__':
p = Process(target=task)
p.start()
p.join() # 确保子进程代码结束再打印money
print(money) # 999
# 你会发现修改不了,因为进程之间的数据默认是隔离的,但是也可以打破
进程对象属性、方法
# 查看进程号
1. current_process函数
from multiprocessing import Process, current_process
current_process().pid
# 进程号的用处之一:通过代码管理进程
windows taskkill关键字
mac/linux kill关键字
2. os模块
os.getpid() # 获取当前进程的进程号
os.getppid() # 获取当前进程的父进程号
# 杀死子进程
terminate()
# 判断子进程是否存活
is_alive()
僵尸进程、孤儿进程
# 僵尸进程
所有的子进程在运行结束之后都会变成僵尸进程(没死透)
还保留着pid(进程号)和一些运行过程的中的记录便于主进程查看(短时间保存)
这些信息会被主进程回收(彻底死了)
1.主进程正常结束
2.调用join方法
# 孤儿进程
子进程存活着,父进程意外死亡,子进程会被操作系统自动接管
守护进程
# 守护进程(daemon)即将设置为守护进程的子进程的死亡与否参考守护的对象,对象死亡则守护进程立即死亡
from multiprocessing import Process
import time
def task(name):
print(f'{name}活着')
time.sleep(3)
print(f'{name}死了')
if __name__ == '__main__':
p = Process(target=task, args=('子进程',))
# 守护进程必须写在start前面
p.daemon = True # 子进程设置为守护进程
p.start()
# p.join()
print('主进程死亡')
# 加入join()
'''
子进程活着
子进程死了
主进程死亡
'''
# 注释掉join()
# 主进程死亡(主进程结束 子进程立刻结束)
互斥锁
当多个进程操作同一份数据的时候会造成数据的错乱,这个时候需要加锁处理(互斥锁)
将并发变成串行,牺牲了效率但是保障了数据的安全
互斥锁影响程序的效率可能会产生死锁,慎用!
from multiprocessing import Process, Lock
mutex = lock() # 定义互斥锁
mutex.acquire() # 抢锁
mutex.release() # 放锁

浙公网安备 33010602011771号