3 获取当前父进程编号
os.getppid()
表示获取当前父进程编号
示例代码:
# 导入进程包 import multiprocessing import time # 导入获取进程编号相关的模块 import os # 唱歌任务 def sing(): print('sing(): ') # 获取当前进程的id sing_process_id = os.getpid() # 获取当前进程对象 sing_process_object = multiprocessing.current_process() print(sing_process_object, sing_process_id) print('父进程编号:', os.getppid()) for i in range(5): print('唱歌中...') time.sleep(0.2) # 跳舞任务 def dance(): print('dance(): ') # 获取当前进程的id dance_process_id = os.getpid() # 获取当前进程对象 dance_process_object = multiprocessing.current_process() print(dance_process_object, dance_process_id) print('父进程编号:', os.getppid()) for i in range(5): print('跳舞中...') time.sleep(0.2) # 判断当前运行的是否为主进程 if __name__ == '__main__': print('main: ') # 获取当前进程的id main_process_id = os.getpid() # 获取当前进程对象 main_process_object = multiprocessing.current_process() print(main_process_object, main_process_id) # 创建跳舞的子进程 dance_process = multiprocessing.Process(group=None, target=dance, name='dance') # 创建唱歌的子进程 sing_process = multiprocessing.Process(target=sing, name='sing') # 启动子进程 dance_process.start() sing_process.start()
4 扩展
获取进程名
语法:
进程对象.name
# 导入进程包 import multiprocessing import time # 导入获取进程编号相关的模块 import os # 唱歌任务 def sing(): print('sing(): ') # 获取当前进程对象 sing_process_object = multiprocessing.current_process() print('进程名:', sing_process_object.name) for i in range(5): print('唱歌中...') time.sleep(0.2) # 判断当前运行的是否为主进程 if __name__ == '__main__': print('main: ') # 获取当前进程对象 main_process_object = multiprocessing.current_process() print('进程名:', main_process_object.name) # 创建唱歌的子进程 sing_process = multiprocessing.Process(target=sing, name='sing') # 启动子进程 sing_process.start()
根据进程编号强制杀死指定进程
语法
import os # 第二个参数为杀死进程的方式,9 -- 强制杀死进程 os.kill(要杀死的进程编号, 9)
# 导入进程包 import multiprocessing import time # 导入获取进程编号相关的模块 import os # 唱歌任务 def sing(): print('sing(): ') # 获取当前进程对象 sing_process_object = multiprocessing.current_process() print('进程名:', sing_process_object.name) for i in range(5): print('唱歌中...') time.sleep(0.2) os.kill(os.getpid(), 9) # 判断当前运行的是否为主进程 if __name__ == '__main__': print('main: ') # 获取当前进程对象 main_process_object = multiprocessing.current_process() print('进程名:', main_process_object.name) # 创建唱歌的子进程 sing_process = multiprocessing.Process(target=sing, name='sing') # 启动子进程 sing_process.start()
进程执行带有参数的任务
1. 进程执行带有参数的任务的介绍
Process类执行任务并给任务传参数有两种方式:
(1)args 表示以元组的方式给执行任务传参
(2)kwargs 表示以字典方式给执行任务传参
2. args参数的使用
元组方式传参(args): 元组方式传参一定要和参数的顺序保持一致。
使用元组的方式进行传参,如果参数只有一个,元组的第一个逗号不能省略。
import multiprocessing # 显示信息的任务 def show_info(name, age): print(name, age) if __name__ == '__main__': # 创建子进程 # 向任务传参使用 args 元组方式传参 show_info_process = multiprocessing.Process(target=show_info, args=('zs', 20)) # 启动子进程 show_info_process.start()
3. kwargs参数的使用
字典方式传参(kwargs): 字典方式传参字典中的key一定要和参数名保持一致。
import multiprocessing # 显示信息的任务 def show_info(name, age): print(name, age) if __name__ == '__main__': # 创建子进程 # 向任务传参使用 args 元组方式传参 show_info_process = multiprocessing.Process(target=show_info, kwargs={'name': 'zs', 'age': 29}) # 启动子进程 show_info_process.start()
第一个参数的传递使用元组,第二个参数的传递使用字典:
import multiprocessing # 显示信息的任务 def show_info(name, age): print(name, age) if __name__ == '__main__': # 创建子进程 # 向任务传参使用 args 元组方式传参 show_info_process = multiprocessing.Process(target=show_info, args=('zs',), kwargs={'age': 29}) # 启动子进程 show_info_process.start()
进程的注意点
1. 进程的注意点介绍
(1)进程之间不共享全局变量
(2)主进程会等待所有的子进程执行结束再结束
2. 进程之间不共享全局变量
创建子进程会对主进程资源进行拷贝,也就是说子进程是主进程的一个副本,好比是一对双胞胎,之所以进程之间不共享全局变量,是因为操作的不是同一个进程里面的全局变量,是不同进程里面名字相同的全局变量。
Windows下多进程程序,如果在主进程中没有
if __name__ == '__main__':
,会报错,因为创建子进程会对主进程资源进行拷贝,也就是说,子进程的代码与主进程一模一样,当主进程调用子进程时,由于子进程中存在直接执行新建子进程和调用子进程的代码,会出现无限递归调用,所以会报错。如果加上if __name__ == '__main__':
判断,不是主进程就不会执行新建子进程和调用子进程的代码。
import multiprocessing import time # 定义全局变量 g_list = list() # 添加数据的任务 def add_data(): for i in range(5): g_list.append(i) print("add:", i) time.sleep(0.2) # 代码执行到此,说明数据添加完成 print("add_data:", g_list) def read_data(): print("read_data", g_list) if __name__ == '__main__': # 创建添加数据的子进程 add_data_process = multiprocessing.Process(target=add_data) # 创建读取数据的子进程 read_data_process = multiprocessing.Process(target=read_data) # 启动子进程执行对应的任务 add_data_process.start() # 主进程等待添加数据的子进程执行完成以后程序再继续往下执行,读取数据 add_data_process.join() read_data_process.start() print("main:", g_list) # 总结: 多进程之间不共享全局变量
进程之间不共享全局变量的解释效果图:
3. 主进程会等待所有的子进程执行结束再结束
假如我们现在创建一个子进程,这个子进程执行完大概需要2秒钟,现在让主进程执行0.5秒钟就退出程序,查看一下执行结果,示例代码如下:
import multiprocessing import time # 定义进程所需要执行的任务 def task(): for i in range(10): print("任务执行中...") time.sleep(0.2) if __name__ == '__main__': # 创建子进程 sub_process = multiprocessing.Process(target=task) sub_process.start() # 主进程延时0.5秒钟 time.sleep(0.5) print("over") exit() # 总结: 主进程会等待所有的子进程执行完成以后程序再退出
4. 主进程结束整个程序结束
为了保证子进程能够正常的运行,主进程会等所有的子进程执行完成以后再销毁,设置守护主进程的目的是主进程退出子进程销毁,不让主进程再等待子进程去执行。
- 守护主进程:
- 守护主进程就是主进程退出子进程销毁不再执行,主进程结束执行,整个程序结束执行。
- 语法:
子进程对象.daemon = True
- 子进程销毁:
- 主进程要结束时候,将子进程销毁,子进程执行结束,整个程序结束。
- 语法:
子进程对象.terminate()
4.1 设置守护主进程:
在pycharm中可能执行不出效果,需要在终端执行代码。(Windows)
import multiprocessing import time # 定义进程所需要执行的任务 def task(): for i in range(10): print("任务执行中...") time.sleep(0.2) if __name__ == '__main__': # 创建子进程 sub_process = multiprocessing.Process(target=task) # 设置守护主进程,主进程退出子进程直接销毁,子进程的生命周期依赖与主进程 sub_process.daemon = True sub_process.start() time.sleep(0.5) print("over") # 总结: 主进程会等待所有的子进程执行完成以后程序再退出 # 如果想要主进程退出子进程销毁,可以设置守护主进程或者在主进程退出之前让子进程销毁
4.2 主进程结束时子进程销毁:
在pycharm中可能执行不出效果,需要在终端执行代码。(Windows)
import multiprocessing import time # 定义进程所需要执行的任务 def task(): for i in range(10): print("任务执行中...") time.sleep(0.2) if __name__ == '__main__': # 创建子进程 sub_process = multiprocessing.Process(target=task) sub_process.start() time.sleep(0.5) print("over") # 让子进程销毁 sub_process.terminate() exit() # 总结: 主进程会等待所有的子进程执行完成以后程序再退出 # 如果想要主进程退出子进程销毁,可以设置守护主进程或者在主进程退出之前让子进程销毁