5

サブプロセスの強制終了に問題があります。次のコードは、サブプロセスの作成に使用されます-

  while(not myQueue.empty()): 
        p=Popen(myQueue.get(),shell=True,stdin=PIPE,stderr=PIPE)

キュー(コマンドが含まれている)が空になるまで反復してプロセスを作成しています。変数pはグローバルであり、タイプPopenのオブジェクトです。コマンドが本来の動作を実行したにもかかわらず、停止ボタンで問題が発生し、期待どおりにプロセスが停止しません。

停止ボタンのコードは次のとおりです-

  stop=Button(textBoxFrame,text="Stop",width=5,command=stopAll)
  stop.grid(row=1,column=4)

stopAllメソッドは、現在のサブプロセスpを強制終了する上記の停止ボタンによって呼び出されます。

  def stopAll():
        p.kill()

注–エラー、例外、またはコンパイルの問題はありません。

更新: 問題は、p.kill()私が殺す必要のあるプロセスを殺していなかったことです。を使用してunixでこれを確認しまし>> ps auxた。また、PIDの開始と終了を出力するようにプログラムを作成したので、で確認できますps aux。強制終了する必要のあるプロセスが6PID離れていることがわかりました。動作しているプロセスを強制終了してp.pidos.kill((p.pid)+6,signal.SIGKILL)正しいプロセスを停止してみました。しかし、さまざまな子プロセスが強制終了される可能性があるため、そのようにはしたくありません。私は私の問題についてより多くの詳細を与えています-

ここで使用しているキューには、前に述べたようにコマンドが含まれています。コマンドは次のようなものです-

    echo "Hello"|festival --tts

FestivalはUNIXの音声合成装置でありfestival --tts、ファイルからユーザー入力を取得します。私は"Hello"お祭りに向かっています、そしてそれは言葉を正しく言います。しかしp、上記のコマンドを実行するプロセスは、殺害であり、ではechoありませんfestival。だから、特定の(フェスティバル)プロセスを殺すのを手伝ってください。

4

4 に答える 4

1

たとえば、stopAll()関数内でstopPressedをグローバルとして宣言していないため、問題が発生している可能性があります。

>>> fred = '20'
>>> def updateFred(age):
...     fred=age
>>> updateFred(40)
>>> fred
'20'
>>> def updateFred(age):
...     global fred
...     fred=age
>>> updateFred(40)
>>> fred
40

おそらく、stopAll()の先頭に「globalstopPressed」を追加すると役立ちますか?

于 2011-08-14T07:56:59.457 に答える
0

もっとコードが必要だと思います。ボタンが押された場合の処理​​方法がわかりません(スレッドの問題が疑われます)。また、stopprcsを最初のループの外側ではなく内側に含めるべきではありませんか?間隔の問題(またはここに問題がありますか?)

于 2011-08-14T07:31:47.883 に答える
0

@aidが述べたように、ハンドルを明示的にグローバルにしないと、他のすべての人のために変更することはできません。stopAll関数の代わりにこれを試してください

def stopAll():
    global stopPressed
    stopPressed=True

グローバルをいじる代わりに、次のようなクラスを作成しないことをお勧めします。

class GuiController(object):
    # if you want the stopPressed to be a static variable accross all
    # GuiController instances uncomment the next line and comment out the __init__
    #stopPressed = False
    def __init__(self):
        self.stopPressed=False
    def main(self):
        while(not myQueue.empty()): 
            p=Popen(myQueue.get(),shell=True,stdin=PIPE,stderr=PIPE)
            while(p.returncode==None):
                if(stopPressed==True):
                    p.kill()
                    break
        self.stopPressed=False
    def stopAll(self):
        self.stopPressed=True
于 2011-08-15T05:09:38.817 に答える
0

フェスティバルプログラムはUNIXであるため、preexec_fnを利用できます。Festivalは、殺害を困難にする独自のサブプロセスを作成していたため、この場合、すべてのFestivalプロセスを識別するグループIDを使用することで解決できます。以下のコードを使用してプロセスのグループを作成できます-

   while(not myQueue.empty()): 
    p=Popen(myQueue.get(),shell=True, stdin=PIPE,preexec_fn=os.setsid)

stopAllには、グローバル変数p-が指す子プロセスのグループを強制終了するための次のコードが含まれるようになりました。

    os.killpg(os.getpgid(p.pid), signal.SIGKILL)

生成されたサブプロセスのグループを強制終了します。出典:サブプロセスの操作

于 2011-08-16T08:22:48.353 に答える