1

I am using the open lighting architecture on a Raspberry Pi and I need to be able to start a show that runs in a constant loop with a button and kill that show and start another one with a button. I am using the pyface add-on with 4 buttons. I can start a process, but I cannot kill a process with the buttons.

If you are using ola in the command line you can stop the show by pressing control-c. I have been able to make a gui that can stop the process with tkinter but the same process doesn't work with physical buttons.

    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);
keyneom
  • 815
  • 10
  • 12
user808996
  • 179
  • 4
  • 15
  • related to the question title [start/stop subprocess using a tkinter button](https://gist.github.com/zed/4067619) – jfs Mar 14 '14 at 19:38

3 Answers3

0

when i use the send_signal,it also doesn't work.I don't know why.So i tried to use the os.kill to kill the subprocess.

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)
marsen
  • 101
  • 1
  • 8
  • Have you tried both `p3.terminate()` and `p3.kill()` if the former doesn't work? – jfs Mar 14 '14 at 19:32
0

p3.wait() in your code blocks the loop until the child process ends. If you remove it then you could call:

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

to terminate the process.

os.system() also blocks until the subprocess finishes. You could replace it with:

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

that returns immediately as soon as ola_recorder launches without waiting for it to exit.

To avoid zombies you need to call p.wait() (blocks) or p.poll() (doesn't block). You should call the later until it returns non-None value (meaning that the subprocess exited).

jfs
  • 399,953
  • 195
  • 994
  • 1,670
0

I tried again. It can terminate the process. When i do it like this

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

It indeed has two processes. /bin/sh -c and ping. When i tried terminate(), it kills the /bin/sh -c. So the ping command is running still.

Jones
  • 1,480
  • 19
  • 34
marsen
  • 101
  • 1
  • 8
  • See [How to terminate a python subprocess launched with shell=True](http://stackoverflow.com/q/4789837/4279) – jfs Mar 17 '14 at 12:31