Почему я получаю предупреждения о ресурсах подпроцесса, несмотря на то, что процесс мертв? - PullRequest
5 голосов
/ 07 марта 2019

Я пытался выяснить, как раскрутить разные экземпляры подпроцесса, а затем убить их и создать новые.Родительский процесс Python никогда не делает, он просто убивает подпроцессы.Я перешел по множеству ссылок на SO, но продолжаю получать следующее сообщение после завершения родительского процесса python:

F/Users/Lucifer/miniconda3/envs/rltp/lib/python3.6/subprocess.py:761: ResourceWarning: subprocess 40909 is still running ResourceWarning, source=self)

это интересно, потому что я сделал ps, но ничего не получаю:

  PID TTY           TIME CMD
 7070 ttys001    0:00.06 /Applications/iTerm.app/Contents/MacOS/iTerm2 --server login -fp Lucifer
 7072 ttys001    0:00.61 -bash
17723 ttys002    0:00.06 /Applications/iTerm.app/Contents/MacOS/iTerm2 --server login -fp Lucifer
17725 ttys002    0:00.06 -bash
38586 ttys002    0:00.16 sertop --no_init

Я просто хочу запустить процесс:

self.serapi = subprocess.Popen(['sertop','--no_init'],
    stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,
    preexec_fn=os.setsid,shell=True
    ,)

и уничтожить его:

    os.killpg(os.getpgid(self.serapi.pid), signal.SIGTERM)

приведенный выше код по сути скопирован из верхнего ответа:

Как завершить подпроцесс python, запущенный с shell = True

, но я не уверен, почему я получаю это сообщение.Я успешно убиваю дочерний процесс?Я планирую начать и убить многих из них.


Примечание. Не знаю, не нужно shell=True.Я только что скопировал это, потому что ответ на вопрос / вопрос, который я разместил, есть.Я предпочел бы не иметь этот параметр.


в соответствии с ответом, который я попробовал:

def kill(self):
    self.serapi.wait()
    #self.serapi.kill()
    self.serapi.terminate()
    #os.killpg(os.getpgid(self.serapi.pid), signal.SIGTERM)
    #self.serapi.wait()

и различными перестановками из вышеперечисленного, но на самом деле ничего не получалось.Любой совет?

1 Ответ

2 голосов
/ 07 марта 2019

Предупреждение ResourceWarning: subprocess N is still running исходит из метода __del__ класса subprocess.Popen.

Если вы посмотрите на источник для этого метода , вы увидите этот комментарий:

        # Not reading subprocess exit status creates a zombie process which
        # is only destroyed at the parent python process exit
        _warn("subprocess %s is still running" % self.pid,
              ResourceWarning, source=self)

Решение заключается в том, чтобы вы вызывали wait() для дочернего процесса.

Дополнительную информацию см. В разделе ПРИМЕЧАНИЯ на странице руководства для wait(2).

В Python самый простой способ справиться с этой ситуацией - отследить все созданные вами Popen объекты и убедиться, что что-то вызывает на них wait(), прямо или косвенно.

Кроме того, вы можете установить обработчик SIGCHLD, который игнорирует события SIGCHLD; тогда ваши дочерние процессы немедленно исчезнут, но теперь вы будете неспособны вызвать wait() для них. См. Также Как я могу предотвратить дочерние процессы зомби? и Как я могу обрабатывать SIGCHLD?

...