2013-07-19 4 views
1

Я использую архитектуру открытого освещения на малине Pi, и мне нужно иметь возможность запускать шоу, которое работает в постоянном цикле с помощью кнопки, и убивать это шоу и запускать еще один кнопка. Я использую дополнение pyface с 4 кнопками. Я могу начать процесс, но я не могу убить процесс с помощью кнопок.Как убить подпроцесс с помощью кнопки

Если вы используете ola в командной строке, вы можете остановить шоу, нажав control-c. Я смог создать gui, который может остановить процесс с помощью tkinter, но тот же процесс не работает с физическими кнопками.

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

, связанный с заголовком вопроса [начало/остановка подпроцесса с использованием кнопки tkinter] (https://gist.github.com/zed/4067619) – jfs

ответ

0

, когда я использую send_signal, он также не work.I не знаю why.So я пытался использовать 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) 
+0

Вы пробовали использовать как 'p3.terminate()', так и 'p3.kill() ', если первая не работает? – jfs

+0

ОК, я попробовал еще раз. – marsen

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 (это означает, что подпроцесс вышел).

0

Я попробовал еще раз. Он может прекратить процесс. Когда я делаю это так

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

У этого действительно есть два процесса. /bin/sh -c и ping. Когда я попробовал terminate(), он убил /bin/sh -c. Таким образом, команда ping работает все еще.

+0

См. [Как завершить подпроцесс python, запущенный с оболочкой = True] (http://stackoverflow.com/q/4789837/4279) – jfs

Смежные вопросы