进程创建的两个方式
# 开启进程的第一种方式:永远先执行主进程的代码
# 多线程模块导入进程
from multiprocessing import Process
# 导入时间模块
import time
# 定义一个task函数,name函数
def task(name):
"""
主进程
:param name:
:return:
"""
# 输出xx is running
print(f'{name} is running')
# 睡2秒
time.sleep(2)
# 输出xx is gone
print(f'{name} is gone')
# 在本模块执行此方法
if __name__ == '__main__':
# 在Windows环境下,开启进程必须在__name__ == '__main__'下面
# 开启子进程的命令
# 创建一个进程对象p target=task目标是task函数,args=('zs',) 给name赋值zs
p = Process(target=task,args=('zs',)) # 元祖的形式
# 开启一个子进程 start() 开启命令
p.start() # 子进程会copy主进程的初始资料 相当于同时开启子进程和主进程
# 这个信号操作系统接收到之后,会在内存中开辟一个子进程空间,然后再将主进程上所有数据copy加载到子进程,
# 然后再去调用cpu去执行
# 执行主进程
print('主程序-开始') # 只运行主进程和子进程,先执行主进程,开辟进程会很消耗内存
# 输出:
# 主程序-开始
# zsis running
# zsis gone
# 睡3秒
time.sleep(3)
print('主进程-结束')
# 输出:
# 主程序-开始
# zs is running
# zs is gone
# 主进程-结束
# 开启进程的第二种方式:需重构父类
from multiprocessing import Process
import time
# 如果不进行实例化.name属性默认有传参,属性值为MyProcess1
# 创建一个类MyProcess 继承Process
class MyProcess(Process):
# 直接实例化会报错 需要重构父类 先执行父类的run再执行自己的run
# 实例化对象
def __init__(self,name):
# supper()重构父类
super().__init__()
# 属性值为name=属性名name
self.name = name
# 定义一个run方法 实例化
def run(self):
# 输出xx is running
print(f'{self.name} is running')
# 睡2秒
time.sleep(2)
# 输出xx is gone
print(f'{self.name} is gone')
# 在本模块执行此方法
if __name__ == '__main__':
# 实例化对象p 把zs给name
p = MyProcess('zs')
# 启动子进程
p.start()
print('主进程-开始')
# 简单应用
from multiprocessing import Process
import time
def task(name):
print(f'{name} is running')
time.sleep(1)
print(f'{name} is gone')
def task1(name):
print(f'{name} is running')
time.sleep(2)
print(f'{name} is gone')
def task2(name):
print(f'{name} is running')
time.sleep(3)
print(f'{name} is gone')
# 串行执行一个进程中执行三个任务 4.5秒
if __name__ == '__main__':
# 启动时间=当前时间
start_time = time.time()
task('zs')
task1('zs2')
task2('zs3')
# 当前时间-启动时间=运行的时间
print(f'结束时间{time.time()-start_time}')
# 输出
# zs is running
# zs is gone
# zs2 is running
# zs2 is gone
# zs3 is running
# zs3 is gone
# 结束时间6.009660959243774
# 三个进程 并发或者并行的执行三个任务 3秒
if __name__ == '__main__':
start_time = time.time()
p1 = Process(target=task,args=('zs',))
p2 = Process(target=task1,args=('zs2',))
p1.start()
p2.start()
task2('zs3')
print(f'结束时间{time.time()-start_time}')
# 输出
# zs3 is running
# zs is running
# zs2 is running
# zs is gone
# zs2 is gone
# zs3 is gone
# 结束时间3.009711742401123
进程的pid
# 导入os模块
import os
# 导入time模块
import time
# mac 命令行获取所有的进程的pid号 ps-ef
# Windows 命令行获取所有的进程的pid号 tasklist
# 代码级别如何获取一个进程pid号 os.getpid()
print(f'子进程:{os.getpid()}')
# 如何获取父进程(主进程)的pid号 os.getppid()
print(f'主进程:{os.getppid()}')
time.sleep(5) # 睡50秒打开终端,找到Python进程的pid进行核对
from multiprocessing import Process
import time
import os
def task(name): # 再执行子进程
print(f'子进程{os.getpid()}')
print(f'主进程{os.getppid()}')
if __name__ == '__main__':
# 创建一个进程对象
p = Process(target=task,args=('zs',))
p.start()
print(f'主进程的pid{os.getppid()}') # 先执行主进程
# 输出:
# 子进程:6712
# 主进程:590
# 主进程的pid590
# 子进程6713
# 主进程6712
空间隔离
# 怎么执行都是先执行主进程
# 加个sleep睡一会
# 空间隔离
# 子进程修改后的name与主进程的name没有关系
from multiprocessing import Process
import os
import time
# 不可变
name = 'zs'
def task():
global name
name = 'ls'
print(f'子进程{name}') # ls
if __name__ == '__main__':
p = Process(target=task) # 创建一个进程对象
p.start()
time.sleep(3)
print(f'主进程{name}') # zs
# 输出
# 子进程ls
# 主进程zs
# 可变的
lst = ['ww',]
def task():
lst.append('yy')
print(f'子进程{lst}') # ['ww','yy']
if __name__ == '__main__':
p = Process(target=task) # 创建一个进程对象
p.start()
time.sleep(3)
print(f'主进程{lst}') # ['ww']
# 输出
# 子进程['ww', 'yy']
# 主进程['ww']
进程的其他参数
from multiprocessing import Process
import time
# 杀死子进程 terminate()
def task(name):
print(f'{name} is running')
time.sleep(2)
print(f'{name} is gone')
if __name__ == '__main__':
p = Process(target=task,args=('zs',)) # 创建一个进程对象
p.start() # 启动进程
p.terminate() # 杀死子进程
print('主进程')
# 输出
# 主进程
# 只输出主进程,子进程被杀死
from multiprocessing import Process
import time
def task(name):
print(f'{name} is running')
time.sleep(2)
print(f'{name} is gone')
if __name__ == '__main__':
p = Process(target=task, args=('zs',)) # 创建一个进程对象
p.start() # 启动进程
time.sleep(1) # 睡1秒
p.terminate() # 杀死子进程
print('主进程')
# 输出
# zs is running
# 主进程
# 先执行子进程睡一会,再杀死子进程,最后执行子进程
# 查看是否真的杀死子进程 子进程是否还活着is_alive()方法
from multiprocessing import Process
import time
def task(name):
print(f'{name} is running')
time.sleep(2)
print(f'{name} is gone')
if __name__ == '__main__':
p = Process(target=task,args=('zs',)) # 创建一个进程对象
p.start() # 启动子进程
p.terminate() # 杀死子进程
p.join() # 阻塞 还可以用sleep()
print(p.is_alive()) # 判断子进程是否还活着 True活着 False死了
print('主进程')
# 输出
# False
# 主进程
# 增加属性 默认name属性 Process属性值
from multiprocessing import Process
import time
def task(name):
print(f'{name} is running')
time.sleep(2)
print(f'{name} is gone')
if __name__ == '__main__':
p = Process(target=task,args=('zs',),name ='alex') # 创建一个进程对象
p.start() # 启动子进程
p.name = 'ls' # 添加属性
print(p.name) # 打印name :ls
print('主进程')
# 输出:ls
# 主进程
# zs is running
# zs is gone
守护进程
# 守护进程
# 子进程守护者主进程,只要主进程结束,子进程跟着结束 daemon=True
from multiprocessing import Process
import time
def task(name):
print(f'{name} is running')
time.sleep(2)
print(f'{name} is gone')
if __name__ == '__main__':
p = Process(target=task,args=('zs',)) # 创建一个进程对象p
# 将p子进程设置成守护进程,只要主进程结束,守护进程马上结束
p.daemon = True # 在开启子进程之前设置守护进程
p.start()# 开启子进程
time.sleep(1) # 睡一会
print('主进程')
# 输出
# zs is running
# 主进程
僵尸进程和孤儿进程
"""
# 僵尸进程 基于Unix环境(Linux,MacOs)
# 主进程等子进程完成之后,主进程再结束
# ***生命周期:
# 主进程时刻监测子进程的运行状态,当子进程结束之后,一段时间之内,将子进程进行回收
# 为什么主进程不在子进程结束后立马对其回收呢
# 1.主进程与子进程是异步关系,主进程无法马上捕获子进程什么时候结束
# 2.如果子进程结束之后马上在内存中释放资源,主进程就没有办法监测子进程的状态了
# ***Unix针对上面的问题,提供了一个机制
# 所有的子进程结束之后,立马会释放掉文件的操作链接,内存的大部分数据,
但是会保留一个一些内容:进程号,结束时间,运行状态,等待主进程监测,回收
# 僵尸进程:
# 所有的子进程结束之后,在被主进程回收之前,都会进入僵尸状态
# 僵尸进程的危害:
# 如果父进程不对僵尸进程进行回收(wait/waitpid),产生大量的僵尸进程
这样就会占用内存,占用进程pid号
# 孤儿进程:
# 父进程由于某种原因结束了,但是子进程还在运行中,这样这些子进程就变成了孤儿进程。
父进程如果结束了,所有的孤儿进程就会被init进程的回收,init就变成了父进程
# 如何解决僵尸进程:
# 父进程产生了大量子进程,但是不回收,这样就会形成大量的僵尸进程,
解决方式就是直接杀死父进程,将所有的僵尸进程变成孤儿进程,进程由init进行回收
"""
from multiprocessing import Process
import time
import os
def task(name):
print(f'{name} is running')
print(f'主进程:{os.getppid()}')
print(f'子进程:{os.getpid()}')
time.sleep(50)
print(f'{name} is gone')
if __name__ == '__main__':
p = Process(target=task,args=('zs',))
p.start()
print('主程序-开始')
time.sleep(3)
print('主进程-结束')