python3 setproctitle多进程重命名详解
今天由于便于管理,需要修改多进程(包括子进程)的名称,网上的资料不多,基本上没有我想要的案例,今天摸索了下才实现了我的目的,下面具体说一下。
首先,修改进程名,主要依靠一个第三方的模块:setproctitle 详情见:setproctitle · PyPI
用法很简单,基本就两个方法:
setproctitle(title)
Set title as the title for the current process.
getproctitle()
Return the current process title
我们先来一个例子,如下代码:
# -*- coding: utf-8 -*-
from multiprocessing import Process
import time
import setproctitle
def task(name):
print("name=",name)
time.sleep(30)
if __name__ == "__main__":
setproctitle.setproctitle('python3 main--')
start = time.time()
p1 = Process(target=task,args=("safly1",),name='python3 safly1')
p2 = Process(target=task, args=("safly2",),name='python3 safly2')
p3 = Process(target=task, args=("safly3",),name='python3 safly3')
p1.start()
p2.start()
p3.start()
p1.join()
p2.join()
p3.join()
print("main")
print(p1.name)
print(p2.name)
print(p3.name)
end = time.time()
print(end- start)
上面代码在linux下运行后在终端打印的输出为:
输出没有问题,我们再通过ps -ef|grep python命令来看下查找出来的结果:
发现,输出的四个进程为均为:python3 main--
父子进程名均为python3 main--,这是没问题的,因为在启动多进程里,通过fork出来的子进程的内存空间和父进程是一样的。
这里我们需要提醒大家的是,Process(target=task,args=("safly1",),name='python3 safly1') 这里通过name传参数的name并不是修改程序在服务器中运行时系统分配的进程名,这里的name其实就是这个进程环境内的一个属性,也可以看作是这个进程的内存空间里的标记吧,仅此而已,实际中很多同学不小心就默认把它当进程名为对待,这个说法不完全正确。如果需要修改进程在服务器系统中的进程名称,那可以按如下:
# -*- coding: utf-8 -*-
from multiprocessing import Process
import time
import setproctitle
def task(name):
print("name=",name)
time.sleep(30)
if __name__ == "__main__":
setproctitle.setproctitle('python3 main--')
start = time.time()
p1 = Process(target=task,args=("safly1",),name='python3 safly1')
p2 = Process(target=task, args=("safly2",),name='python3 safly2')
p3 = Process(target=task, args=("safly3",),name='python3 safly3')
p1.start()
setproctitle.setproctitle('python3 main--1')
print(setproctitle.getproctitle())
p2.start()
setproctitle.setproctitle('python3 main--2')
print(setproctitle.getproctitle())
p3.start()
setproctitle.setproctitle('python3 main--3')
print(setproctitle.getproctitle())
p1.join()
p2.join()
p3.join()
print("main")
print(p1.name)
print(p2.name)
print(p3.name)
end = time.time()
print(end- start)
上面代码在linux终端上的输出为:
查找进程信息 ps -ef|grep python3
如上所示,就可以通过命令ps来监控查询进程了。
注意注意!!!
也许有人并没有发现上述所存在的问题,我在这里特别说明一下,上面的子进程在使用setproctitle.setproctitle('python3 XX')时是有误的,如上代码,通过PS命令可 以看到父进程ID和子进程ID,和进程名是配对乱了。解决上述问题的核心是,必须在调用的函数task里执行setproctitle.setproctitle才不会导致错乱。如下片段代码为正确的:
def task(queue_name,threads_max):
setproctitle.setproctitle('python3-spider<%s>-start.py' % queue_name)