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)