我正在使用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);
答案 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 -c
和ping
。当我尝试终止()时,它会杀死/bin/sh -c
。所以ping命令仍在运行。