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()  # 放锁