【一】进程的创建
"""特别注意******
不同的操作系统创建进程的要求不—样
在windows 中创建进程是以导入模块的方式进行所以创建进程的代码必须写在_main_子代码中否则会直接报错因为在无限制创建进程
在linux和mac中创建进程是直接拷贝─份源代码然后执行不需要写在_main_子代码中
"""
(1)常见的两种创建进程方式
1.鼠标双击桌面一个应用图标
2.代码创建
(2)创建进程的本质:在内存中申请一块内存空间用于运行相应的程序代码
"""注意:由于是在运行原本脚本的那个进程时得到start命令,才会在内存空间里开辟了一个新的空间创建进程,然后由于异步 ,所以先执行了原本脚本里的print才去另一个进程里执行print"""
(3)创建子进程方式一:使用Process方法实例化得到任务对象
from multiprocessing import Process
# 创建子进程方式一:使用Process方法实例化得到任务对象
# 【一】定义任务函数
def run(name):
print(f' {name} start sport')
time.sleep(random.randrange(1, 5))
print(f' {name} end sport')
if __name__ == '__main__':
# 【二】创建进程对象
# Process(target=被调用的任务名(进程名), args=(参数,))
# args:里面的参数一定要用逗号隔开(容器类型无论里面有几个元素,哪怕只有一个元素,也一定要用逗号隔开)
p1 = Process(target=run, args=('dream',)) # 必须加,号
p1.start()
"""
强调:不同的操作系统创建进程的要求不一样
在windows中创建进程是以导入模块的方式进行 所以创建进程的代码必须写在__main__子代码中
否则会直接报错 因为在无限制创建进程
在linux和mac中创建进程是直接拷贝一份源代码然后执行 不需要写在__main__子代码中
"""
(4)方式二:创建一个新的类继承自Process,重写run方法
class MyProcess(Process):
def __init__(self, name):
super().__init__()
self.name = name
# 【一】定义任务函数
def run(self):
print(f' {self.name} start sport')
time.sleep(random.randrange(1, 5))
print(f' {self.name} end sport')
if __name__ == '__main__':
# 【二】创建子进程
p1 = MyProcess(name='dream')
p1.start()
【二】创建进程时各个参数的介绍
Process([group [, target [, name [, args [, kwargs]]]]])
● group参数未使用,值始终为None
● target表示调用对象,即子进程要执行的任务
● args表示调用对象的位置参数元组,args=(1,2,'ly',)
● kwargs表示调用对象的字典,kwargs={'name':'ly','age':18}
● name为子进程的名称
【三】创建进程时各个方法介绍
● p.start():
○ 启动进程,并调用该子进程中的p.run()
● p.run():
○ 进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法
● p.terminate():
○ 强制终止进程p,不会进行任何清理操作
○ 如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。
○ 如果p还保存了一个锁那么也将不会被释放,进而导致死锁
● p.is_alive():
○ 判断该进程是否还在运行
● p.join([timeout]):
让所有子进程先执行完毕再执行主进程
○ 主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。
○ timeout是可选的超时时间
○ 需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程
【四】进程属性介绍
● p.daemon:
○ 默认值为False
○ 如果设为True,代表p为后台运行的守护进程
○ 当p的父进程终止时,p也随之终止
○ 并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置
● p.name:
○ 进程的名称
● p.pid:
○ 进程的pid
【五】进程号以及杀死进程的相关方法命令
1.进程号:在创建一个进程时,他的pcb会有分配好的进程号
2.查看进程号:
● Windows系统
○ CMD 命令行 tasklist 即可查看
● Mac系统
○ 终端运行 ps aux 即可查看
3.根据指定进程号查看进程
● Mac系统
○ 终端运行 ps aux|grep PID 即可查看
● Windows系统
○ CMD 命令行 tasklist |findstr PID 即可查看
4.查看当前进程的进程号用current_process().pid 方法
5.查看当前进程的进程号os.getpid() 方法
6.查看当前进程的父进程的进程号os.getppid() 方法
current_process().pid == os.getpid()
7.杀死当前进程p.terminate()
8.判断当前进程是否存活p.is_alive()
【六】join方法扩展
join()会阻塞主进程,直到被调用的子进程完成。
所有的
1.非join方法 -- 并行
2.join方法 -- 串行
子进程串行 挨个start然后join,是因为挨个start的话开个内存空间,然后join,那么就要把该子进程执行完
3.join方法 -- 并行
子进程并行 全部start完再全部join,由于子进程都是异步且多道的所以并行
注意:start必须再join之前,若要让主进程的print最后执行,那么一定要在join之后