py_并发_Process类笔记

Process类

如果要想在Python中进行多进程的编写开发,那么就一定要有Python程序内部的模块支持,在进行多进程开发的时候可以使用“multiprocessing”模块进行多线程的编写,而在这个模块内部提供一个Process类,利用这个类可以进行多进程的定义。

Python多进程编写可以通过“multiprocessing”模块实现,在该模块中提供有专门的进程处理类Process

方法 类型 描述
pid 属性 获取进程ID
name 属性 获取进程名称
def _init_([group[,target [,name [,args[,kwargs [,daemon]]]]]]) 构造 创建一个执行进程,参数作用如下: group:分组定义; target:进程处理对象(代替run()方法);name:进程名称,若不设置则自动分配一个名称;args:进程处理对象所需要执行参数; kwargs:调用对象字典; daemon:是否设置为后台进程;
start(self) 方法 进程启动,进入进程调度队列
run(self) 方法 进程处理(不指定target时生效)

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# coding: UTF-8
import multiprocessing as mtp,time #导入多进程开发模块
def worker(delay,count): #多进程的实现需要提供有一个专门的处理函数
for num in range(count): # 依据传入的count的大小来进行循环的控制
# 通过多进程的模块获取当前执行进程的id以及进程名称
print("[%s] 进程ID: %s、进程名称:%s" % (num,
mtp.current_process().pid,
mtp.current_process().name))
time.sleep(delay)
def main(): # 定义执行的主函数
for item in range(3): #迭代3次,每一次都创建一个进程
process = mtp.Process(target=worker, args=(1,4,), name="pythonLearn进程%s" %item) #创建进程对象
process.start() # 进程启动
if __name__ == "__main__": # 判断执行名称
main() #调用主函数

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
D:\Program_software_list\Anaconda3_5\python.exe F:/Learn/Python/untitled1/test.py
[0] 进程ID: 22472、进程名称:pythonLearn进程0
[0] 进程ID: 28748、进程名称:pythonLearn进程1
[0] 进程ID: 27468、进程名称:pythonLearn进程2
[1] 进程ID: 22472、进程名称:pythonLearn进程0
[1] 进程ID: 28748、进程名称:pythonLearn进程1
[1] 进程ID: 27468、进程名称:pythonLearn进程2
[2] 进程ID: 22472、进程名称:pythonLearn进程0
[2] 进程ID: 28748、进程名称:pythonLearn进程1
[2] 进程ID: 27468、进程名称:pythonLearn进程2
[3] 进程ID: 22472、进程名称:pythonLearn进程0
[3] 进程ID: 28748、进程名称:pythonLearn进程1
[3] 进程ID: 27468、进程名称:pythonLearn进程2

进程已结束,退出代码0

所有在程序之中创建的进程都是采用交替的模式执行的(尤其是追加了延迟处理之后,这种交替的运行结果就非常明显了),既然Python的程序可以使用多进程的模式执行,那么在实际的开发之中所有的程序按照标准来讲都需要通过主函数来运行,那么请问Python本身启动的进程信息该如何获取呢?

观察主函数(主进程)

1
2
3
4
5
6
7
8
# coding: UTF-8
import multiprocessing as mtp #导入多进程开发模块
def main():
print("进程ID: %s、进程名称:%s" % (
mtp.current_process().pid,
mtp.current_process().name))
if __name__ == "__main__": # 判断执行名称
main() #调用主函数

运行结果:

1
2
3
4
D:\Program_software_list\Anaconda3_5\python.exe F:/Learn/Python/untitled1/test.py
进程ID: 23492、进程名称:MainProcess

进程已结束,退出代码0

所有的python程序执行都是通过主进程开始的,而后所有通过Process定义的进程都属于子进程。

面向对象的多进程实现

对于现在所编写的多进程程序实际上都是采用了面向对象的编写模式实现的,那么按照面向对象的设计来讲,这种的代码就不太符合于OO的设计思想,如果假设你现在需要通过面向对象的形式进行进程的创建,这个时候就可以直接Process类,同时复写里面的run()方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# coding: UTF-8
import multiprocessing as mtp,time #导入多进程开发模块
class MyProcess(mtp.Process): # 定义进程处理类
def __init__(self,name,delay,count): # 构造方法进行属性初始化
super().__init__(name=name) # 调用父类构造设置进程名称
self.__delay = delay # 保存属性
self.__count = count # 保存属性
def run(self):
for num in range(self.__count):
# 通过多进程模块获取当前进程的id以及进程名称
print("[%s] 进程ID: %s、进程名称:%s" % (num,
mtp.current_process().pid,
mtp.current_process().name))
time.sleep(self.__delay)
def main(): #定义执行的主函数
for item in range(3): #迭代执行三次,每次都创建一个进程
process = MyProcess(name="pythonLeanrn%s" % item, delay=1, count=10) # 创建进程对象
process.start() #不是调用run(),而是调用start()
if __name__ == "__main__": # 判断执行名称
main() #调用主函数

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
D:\Program_software_list\Anaconda3_5\python.exe F:/Learn/Python/untitled1/test.py
[0] 进程ID: 28908、进程名称:pythonLeanrn0
[0] 进程ID: 30600、进程名称:pythonLeanrn1
[0] 进程ID: 13948、进程名称:pythonLeanrn2
[1] 进程ID: 28908、进程名称:pythonLeanrn0
[1] 进程ID: 30600、进程名称:pythonLeanrn1
[1] 进程ID: 13948、进程名称:pythonLeanrn2
[2] 进程ID: 28908、进程名称:pythonLeanrn0
[2] 进程ID: 30600、进程名称:pythonLeanrn1
[2] 进程ID: 13948、进程名称:pythonLeanrn2
[3] 进程ID: 28908、进程名称:pythonLeanrn0
[3] 进程ID: 30600、进程名称:pythonLeanrn1
[3] 进程ID: 13948、进程名称:pythonLeanrn2
[4] 进程ID: 28908、进程名称:pythonLeanrn0
[4] 进程ID: 30600、进程名称:pythonLeanrn1
[4] 进程ID: 13948、进程名称:pythonLeanrn2
[5] 进程ID: 28908、进程名称:pythonLeanrn0
[5] 进程ID: 30600、进程名称:pythonLeanrn1
[5] 进程ID: 13948、进程名称:pythonLeanrn2
[6] 进程ID: 28908、进程名称:pythonLeanrn0
[6] 进程ID: 30600、进程名称:pythonLeanrn1
[6] 进程ID: 13948、进程名称:pythonLeanrn2
[7] 进程ID: 28908、进程名称:pythonLeanrn0
[7] 进程ID: 30600、进程名称:pythonLeanrn1
[7] 进程ID: 13948、进程名称:pythonLeanrn2
[8] 进程ID: 28908、进程名称:pythonLeanrn0
[8] 进程ID: 30600、进程名称:pythonLeanrn1
[8] 进程ID: 13948、进程名称:pythonLeanrn2
[9] 进程ID: 28908、进程名称:pythonLeanrn0
[9] 进程ID: 30600、进程名称:pythonLeanrn1
[9] 进程ID: 13948、进程名称:pythonLeanrn2

进程已结束,退出代码0

start()和run()方法的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# coding: UTF-8
import multiprocessing as mtp #导入多进程开发模块
class MyProcess(mtp.Process): # 定义进程处理类
def __init__(self,name): # 构造方法进行属性初始化
super().__init__(name=name) # 调用父类构造设置进程名称
def run(self):
print("进程ID: %s、进程名称:%s" % (
mtp.current_process().pid,
mtp.current_process().name))
def main(): #定义执行的主函数
process = MyProcess(name="pythonLeanrn进程") # 创建进程对象
process.start() #不是调用run(),而是调用start()
process.run()
if __name__ == "__main__": # 判断执行名称
main() #调用主函数

运行结果:

1
2
3
4
5
D:\Program_software_list\Anaconda3_5\python.exe F:/Learn/Python/untitled1/test.py
进程ID: 31380、进程名称:MainProcess
进程ID: 24528、进程名称:pythonLeanrn进程

进程已结束,退出代码0

运行结果的第一行,输出的是run方法的调用,所以如果直接使用run()方法进行进程的调用,那么最终可以执行的只能够是当前进程的一个信息的获取而没有启动新的进程;

第二行是start()方法的输出,可见他启动了子进程,输出了子进程的信息;

所以进程的启动必须通过start()方法才可以正常完成。


py_并发_Process类笔记
https://blog.wangxk.cc/2020/01/15/py-并发-Process类笔记/
作者
Mike
发布于
2020年1月15日
许可协议