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. 我发现我需要杀死的进程距离 6 个 PID p.pid,我尝试杀死os.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() 的开头添加“global stopPressed”会有所帮助?

于 2011-08-14T07:56:59.457 回答
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

我认为需要更多代码。我不确定您如何处理按下按钮的事件(怀疑是线程问题)。另外,stopprcs 不应该包含在第一个循环中而不是外部吗?间距问题(或者问题就在这里?)。

于 2011-08-14T07:31:47.883 回答
0

由于节日程序在 UNIX 中,我们可以使用 preexec_fn。Festival 正在创建自己的子进程,这使得杀戮变得更加困难,因此在这种情况下,使用标识所有节日进程的 group 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 回答