0

以下のコードがフリーズする理由が気になります。python3 インタプリタを kill すると、"cat" プロセスがゾンビとして残ります。メインプロセスが終了する前にサブプロセスが終了することを期待しています。

手動で SIGTERM を に送信するcat /dev/zeroと、プロセスは正しく終了します (ほとんどすぐに)

#!/usr/bin/env python3
import subprocess
import re
import os
import sys
import time
from PyQt4 import QtCore

class Command(QtCore.QThread):
#    stateChanged = QtCore.pyqtSignal([bool])

    def __init__(self):
        QtCore.QThread.__init__(self)
        self.__runned = False
        self.__cmd = None
        print("initialize")

    def run(self):
        self.__runned = True

        self.__cmd = subprocess.Popen(["cat /dev/zero"], shell=True, stdout=subprocess.PIPE)
        try:
            while self.__runned:
                print("reading via pipe")
                buf = self.__cmd.stdout.readline()
                print("Buffer:{}".format(buf))
        except:
            logging.warning("Can't read from subprocess (cat /dev/zero) via pipe")
        finally:
            print("terminating")
            self.__cmd.terminate()
            self.__cmd.kill()

    def stop(self):
        print("Command::stop stopping")
        self.__runned = False
        if self.__cmd:
            self.__cmd.terminate()
            self.__cmd.kill()
            print("Command::stop stopped")


def exitApp():
    command.stop()
    time.sleep(1)
    sys.exit(0)


if __name__ == "__main__":
    app = QtCore.QCoreApplication(sys.argv)
    command = Command()
#    command.daemon = True
    command.start()
    timer = QtCore.QTimer()
    QtCore.QObject.connect(timer, QtCore.SIGNAL("timeout()"), exitApp)
    timer.start(2 * 1000)
    sys.exit(app.exec_())
4

2 に答える 2

2

あなたが指摘したように、ゾンビの理由は、シグナルがシェルによってキャッチされ、それによって作成されたプロセスに影響を与えないことです。ただし、シェルとそれによって作成されたすべてのプロセスを強制終了する方法があります。プロセスグループ機能を使用する必要があります。shell=True で起動された python サブプロセスを終了する方法を参照shell=Trueください。

于 2012-10-22T09:14:07.473 に答える
0

別の方法でこの問題を解決したので、結果は次のとおりです。subprocess.Popen を shell=False で呼び出す必要があります。そうしないと、2 つのプロセス (シェルとプロセス) が作成され、__cmd.kill() がシェルにシグナルを送信している間に "プロセス」はゾンビのまま

于 2012-08-08T14:15:27.383 に答える