Python3重命名进程名/线程名实现
一、环境准备
项目地址:https://github.com/dvarrazzo/py-setproctitle
安装:pip install setproctitle
二、重命名进程名
2.1 单进程中实现进程重命名
import setproctitle # 获取当前进程名 # Windows可能有问题 proc_title = setproctitle.getproctitle() print(proc_title) # 重命名进程名 proc_title = "new_proc_title" setproctitle.setproctitle(proc_title) proc_title = setproctitle.getproctitle() print(proc_title)
2.2 多进程中实现进程重命名
在单进程中重命名进程名意义并不是很大。在多进程中由于子进程的异常会导致子进程的退出但并不会导致主进程的退出,但由于所有子进程进程名是一样的我们不好判断是哪个子进程出了问题。
此时如果重命名了子进程,我们通过ps就能容易地知道是哪个子进程退出了。
import time import setproctitle import multiprocessing def sub_process(proc_title): proc_title_old = setproctitle.getproctitle() print(f"proc_title_old: {proc_title_old}") setproctitle.setproctitle(proc_title) proc_title_new = setproctitle.getproctitle() print(f"proc_title_new: {proc_title_new}") # time.sleep(10) def main_process(): process_list = [] # 创建进程1 proc_title = "python sub_process_1" tmp_process = multiprocessing.Process(target=sub_process,args=(proc_title,)) process_list.append(tmp_process) # 创建进程2 proc_title = "python sub_process_2" tmp_process = multiprocessing.Process(target=sub_process, args=(proc_title,)) process_list.append(tmp_process) # 启动所有进程 for process in process_list: process.start() for process in process_list: process.join() if __name__ == "__main__": main_process()
可以看到修改进程名前,父进程及启动的两个子进程都是同样的进程名:
进行修改后,子进程进程名成功改变:
(不过之前发现多进程中,如果进程中又启线程池那么可能会导致进程出错并退出,当前不清楚还有没有这种情况。)
三、重命名线程名
根据setproctitle文档描述,其应该支持getthreadtitle()和setthreadtitle(thread_title)来获取和设置线程名,但现在测试看提示不存在这两个方法。
3.1 常规重命名线程名
import threading # 获取当前线程名 thread_title = threading.current_thread().name print(thread_title) # 获取当前线程 thread_obj = threading.current_thread() # 重命名线程名 thread_obj.name = "new_thread_title" thread_name = threading.current_thread().name print(thread_name)
3.2 线程池中自定义线程名前辍
线程池默认前辍是ThreadPoolExecutor-0,线程名就依次是ThreadPoolExecutor-0_0、ThreadPoolExecutor-0_1这样下去。
可使用ThreadPoolExecutor的thread_name_prefix参数自定义线程的前辍。如自定义为my_thread_name,线程名就会依次为my_thread_name_0、my_thread_name_1这样下去。
import time import threading from concurrent.futures import ThreadPoolExecutor class TestClass(): def __init__(self): # 线程池+线程同步改造添加代码处1/5: 定义锁和线程池 # 我们第二大节中说的是锁不能在线程类内部实例化,这个是调用类不是线程类,所以可以在这里实例化 self.threadLock = threading.Lock() # 定义2个线程的线程池 # 使用thread_name_prefix self.thread_pool = ThreadPoolExecutor(2, thread_name_prefix="my_thread_name") # 定义2个进程的进程池。进程池没用写在这里只想表示进程池的用法和线程池基本一样 # self.process_pool = ProcessPoolExecutor(2) pass def main_logic(self): for i in range(4): # 线程池+线程同步改造添加代码处3/5: 注释掉原先直接调的do_something的形式,改成通过添加的中间函数调用的形式 # self.do_something(i) self.call_do_something(i) pass # 线程池+线程同步改造添加代码处2/5: 添加一个通过线程池调用do_something的中间方法。参数与do_something一致 def call_do_something(self, para): self.thread_pool.submit(self.do_something, para) def do_something(self, para): thread_name = threading.current_thread().name # 线程池+线程同步改造添加代码处4/5: 获取锁 self.threadLock.acquire() print(f"this is thread : {thread_name}") print(f"the parameter value is : {para}") # 线程池+线程同步改造添加代码处5/5: 释放锁 self.threadLock.release() time.sleep(1) pass if __name__ == "__main__": obj = TestClass() obj.main_logic()