簡體   English   中英

如何在python中“采用”子進程

[英]How to “adopt” a child process in python

我如何獲取未為其創建對象的子進程的pid?

myProc = Popen(["sleep","30"])

Popen(["sleep","30"])

我注意到,如果在發送終止信號后不對它們進行poll()或wait(),它們將成為僵屍進程。 在腳本的某個時刻,我想找到腳本作為其父級的所有子進程,並向它們發送信號或對其進行輪詢。 這可能在python中嗎? 有可能嗎?

您可以使用psutil查找父Python進程的子進程。 例如:

import psutil
import os
import subprocess

subprocess.Popen(['sleep', '30'])

parent_pid = os.getpid()
parent = psutil.Process(parent_pid)

for child in parent.children():
    print(child)    # do something here

印刷品:

psutil.Process(pid=16822, name='sleep')

您可以從那里輪詢,殺死它們等。

通常,您不需要執行任何操作-當前的subprocess實現維護活動的未引用Popen實例的全局列表,並且在創建新的Popen對象時,此列表將枚舉,並為每個進程調用.poll()

因此,如果您沒有對子流程的引用; 它會自動等待您(如果您有引用,則可以自己調用.wait() )。

如果子進程是通過其他方式創建的,則可以調用os.waitpid()來收集Unix上死子進程的退出狀態:

while True:
    try:
        pid, status = os.waitpid(-1, os.WNOHANG) 
    except ChildProcessError:
        #  No more child processes exist
        break
    else:
        assert pid, "child process is still alive"

在POSIX.1-2001系統上,您可以調用signal(SIGCHLD, SIG_IGN)來自動收割子代。

如果您想在父母去世時殺死所有孩子(發出信號); 您可以在Linux上使用prctl PR_SET_PDEATHSIG 如果父母因任何原因去世,它就可以工作,即使父母被SIGKILL殺死也可以。

psutil@ali_m的回答是一個便攜的解決方案:

#!/usr/bin/env python
import gc
import subprocess
import time

import psutil


for _ in range(10):
    subprocess.Popen(['sleep', '1'])  # no reference
time.sleep(2)  # wait until they are dead
gc.collect()  # run garbage collection, to populate _active list
subprocess.Popen(['sleep', '1'])  # trigger _cleanup()

for i in range(2):
    for child in psutil.Process().children():  # immediate children
        print(child, child.status())
    if i == 0:
        time.sleep(2)

輸出量

psutil.Process(pid=31253, name='sleep') sleeping
psutil.Process(pid=31253, name='sleep') zombie

注意:

  1. psutil僅顯示一個僵屍進程,其余的將在最后一個Popen()調用中獲得
  2. psutil提供了防止pid重用的保護,但並非在所有情況下都是100%可靠的-檢查您的情況是否足夠(否則,請使用上面一種不依賴child的pid )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM