如何使用按钮终止子进程

时间:2013-07-19 02:32:06

标签: python subprocess raspberry-pi

我正在使用Raspberry Pi上的开放式照明架构,我需要能够启动一个带有按钮的恒定循环运行的节目并杀死该节目并使用按钮启动另一个节目。我正在使用带有4个按钮的pyface插件。我可以开始一个过程,但我不能用按钮杀死一个进程。

如果在命令行中使用ola,可以按control-c停止播放。我已经能够制作一个可以使用tkinter停止进程的gui,但同样的过程不适用于物理按钮。

    from time import sleep
    import os
    import signal
    import piface.pfio as pfio
    import time
    import threading 
    from subprocess import Popen
    import subprocess
    import Queue

    pfio.init()
    pfio.digital_read(0)
    pfio.digital_read(1)
    pfio.digital_read(2)

    def olaserverStart ():
      os.system('olad -l 3')

    def show1():
        os.system('ola_recorder -p /home/pi/Mermaid -i 0')

    def stop():
        try:
            sig = signal.CTRL_C_EVENT
        except AttributeError:
            sig = signal.SIGINT
        send_signal(sig)

    def universe():
      global proc3
      proc3 = subprocess.Popen('ola_patch -d 12 -p 0 -u 0', shell=True)
      proc3.wait()

    def universe1():
        global proc4
        proc4 = subprocess.Popen('ola_patch -d 6 -p 0 -u 0', shell=True)
        proc4.wait()


    olaserverStart()
    universe()
    universe1()



  while True:
        if (pfio.digital_read(0) == 1):
                p3 = subprocess.Popen('ola_recorder -p /home/pi/Mermaid -i 0', shell=True)
                p3.wait()
        if (pfio.digital_read(1) == 1):
          try:
            sig = signal.CTRL_C_EVENT
          except AttributeError:
            sig = signal.SIGINT
          p3.send_signal(sig)
        if (pfio.digital_read(2) == 1):
                os.system('ola_recorder -p /home/pi/Mermaid -i 0')
        sleep(0.15);

3 个答案:

答案 0 :(得分:0)

当我使用send_signal时,它也不起作用。我不知道为什么。所以我试图使用os.kill来杀死子进程。

pp = subprocess.Popen("ping www.google.com",stdin = subprocess.PIPE,stdout =            subprocess.PIPE,stderr = subprocess.PIPE,shell = True)
os.kill(pp.pid+1,signal.SIGTERM)

答案 1 :(得分:0)

代码中的

p3.wait()会阻止循环,直到子进程结束。如果你删除它,那么你可以打电话:

if p.poll() is None:
   p.terminate()
   p.wait()

终止该过程。

os.system()也会阻塞,直到子流程完成。您可以将其替换为:

subprocess.Popen('ola_recorder -p /home/pi/Mermaid -i 0'.split())

ola_recorder启动时立即返回,而不等待它退出。

要避免僵尸,您需要调用p.wait()(阻止)或p.poll()(不阻止)。你应该调用后者,直到它返回非None值(意味着退出子进程)。

答案 2 :(得分:0)

我再试一次。它可以终止进程。当我这样做的时候

pp = subprocess.Popen("ping www.google.com", stdin=subprocess.PIPE, stdout= subprocess.PIPE,stderr = subprocess.PIPE,shell = True)

它确实有两个过程。 /bin/sh -cping。当我尝试终止()时,它会杀死/bin/sh -c。所以ping命令仍在运行。