1

我在 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);
4

3 回答 3

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 命令仍在运行。

于 2014-03-17T01:03:48.937 回答
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()(blocks) 或p.poll()(doesn't block)。您应该调用后者,直到它返回非 None 值(意味着子进程退出)。

于 2014-03-14T19:47:52.853 回答
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)
于 2014-03-14T09:22:42.617 回答