1

I'm trying to kill a subprocess started with:

playing_long = Popen(["omxplayer", "/music.mp3"], stdout=subprocess.PIPE)

and after a while

pid = playing_long.pid
playing_long.terminate()
os.kill(pid,0)
playing_long.kill()

Which doesn't work. Neither the solution pointed out here

How to terminate a python subprocess launched with shell=True

Noting that I am using threads, and it is not recommended to use preexec_fn when you use threads (or at least this is what I read, anyway it doesn't work either).

Why it is not working? There's no error message in the code, but I have to manually kill -9 the process to stop listening the mp3 file.

Thanks

EDIT: From here, I have added a wait() after the kill(). Surprisingly, before re-starting the process I check if this is still await, so that I don't start a chorus with the mp3 file.

  • Without the wait(), the system sees that the process is alive.

  • With the wait(), the system understands that the process is dead and starts again it.

  • However, the process is still sounding. Definitively I can't seem to get it killed.

EDIT2: The problem is that omxplayer starts a second process that I don't kill, and it's the responsible for the actual music.

  • I've tried to use this code, found in several places in internet, it seems to work for everyone but not for me

    playing_long.stdin.write('q')
    playing_long.stdin.flush()
    

And it prints 'NoneType' object has no attribute 'write'. Even when using this code immediately after starting the popen process, it fails with the same message

playing_long = subprocess.Popen(["omxplayer", "/home/pi/Motion_sounds/music.mp3"], stdout=subprocess.PIPE)
time.sleep(5)
playing_long.stdin.write('q')
playing_long.stdin.flush()

EDIT3: The problem then was that I wasn't establishing the stdin line in the popen line. Now it is

playing_long = subprocess.Popen(["omxplayer", "/home/pi/Motion_sounds/music.mp3"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
time.sleep(5)
playing_long.stdin.write(b'q')
playing_long.stdin.flush()

*needing to specify that it is bytes what I write in stdin

Cœur
  • 37,241
  • 25
  • 195
  • 267
GWorking
  • 4,011
  • 10
  • 49
  • 90
  • 3
    To mark the topic as solved, add your answer and accept it. Don't change the title. Or delete the question. – warvariuc Jan 25 '15 at 18:32
  • you should [post your edit 3 as an answer](http://stackoverflow.com/help/self-answer) and accept it. `preexec_fn=setsid` + `os.killpg(pid, SIGKILL)` should work in general (unless omxplayer descendants create their own process groups). Note: it is `killpg`, not just `kill`. Unrelated: do not use `stdout=PIPE` unless you read from `playinglong.stdout` pipe somewhere in your program otherwise the process may stall. If you want to suppress the output from a subprocess, [use this answer](http://stackoverflow.com/a/11270665/4279). – jfs Jan 27 '15 at 07:19

1 Answers1

0

Final solution then (see the process edited in the question):

playing_long = subprocess.Popen(["omxplayer", "/home/pi/Motion_sounds/music.mp3"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
time.sleep(5)
playing_long.stdin.write(b'q')
playing_long.stdin.flush()
GWorking
  • 4,011
  • 10
  • 49
  • 90