一、環境准備
項目地址: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()