Tuesday 24 November 2009

killing Python processes...

I'm playing with some midi based Python stuff at the moment, doing raw file access to /dev/midi1 (midisport uno), and most of the time it's just sitting on a file.read(1). In Windows, the user can break into this with Ctrl-Break (Ctrl-C doesn't work on Windows or Linux), but there doesn't seem to be an equivalent to Ctrl-Break in the Linux world. So it's Ctrl-Z to put it in the background, ps -a, find the program, then terminate it hastily with sudo kill -9. All of which is a bit excessive. Rather than put something proper in there to terminate it (is select() the way to do these things on Linux?), I decided to get the wrong way a little less wrong.
I now have a half-way house to getting it a bit simpler:
alias killpy="sudo kill -9 \`ps -a | grep python | head -c 6\`"
And it's then just Ctrl-Z, killpy. I'm sure this isn't the best way of doing things, but I like the fact that it does things the same way I do, but using pipes to communicate, instead of the eye-brain-hand-keyboard loop. And it's the first time I've used the -c option on head (number of bytes to copy to stdout), so I've learnt something!

Of course it doesn't work if there is more than one Python process, or whatever, and yes I do need the sudo and -9.

11 comments:

  1. you should at least use killall instead of this dirty ps | grep.

    ;)

    ReplyDelete
  2. Try pressing control backslash - \ - under Linux. That will cause the process to immediately exit.

    ReplyDelete
  3. +1 to Roger's suggestion! While there are processes that, for their own nefarious reasons, ignore SIGINT, there are few that bother to catch SIGQUIT — and, therefore, control-backslash should be in your arsenal when things get hung up.

    Note that SIGQUIT is actually a request to make a core dump — so, unless your "ulimit" on core dumps is zero, expect a big file named "core" to be left in the process's last known current working directory.

    ReplyDelete
  4. SIGQUIT should work, but if you use bash you might send SIGSTOP (CTRL+Z) and then do 'sudo kill -9 %1' (or whatever is the number of your job.

    ReplyDelete
  5. Try this to find out which process is being blocked:

    fuser /dev/midi1

    On some systems, fuser isn't in the PATH, and it might be living in /usr/sbin (from memory).

    ReplyDelete
  6. control-z

    and kill -9 %1

    should work !

    ReplyDelete
  7. Why not fork off the raw file access into a process of its own? subprocess.Popen is very easy to use class. Then, if nothing else, make the process object a global and wrap your main() in a try/finally that kills it:

    if __name__ == "__main__":
    ..try:
    ....main()
    ..finally:
    ....myproc.kill()

    ReplyDelete
  8. To echo and build on what gabriel said I would use the following command:

    "your python based command"; sudo killall -9 python

    Then whenever you want to stop your python based program, hit ctrl+z and the next command will automatically be run. It will then "kill -9" every "python" process.

    ReplyDelete
  9. kill %1 is the correct way, it will kill the first background job on the current shell. Use the command 'jobs' to see a list of background jobs.

    ReplyDelete
  10. Ctrl-\ (SIGQUIT), or whatever reports your 'stty -a' after 'quit', would be my first suggestion.

    Otherwise, since you know that it's the /dev/midi1 file that's being waited on, 'fuser -k /dev/midi1' would be my other suggestion.

    ReplyDelete
  11. Thank a lot! I use this line! Helped me very much!

    ReplyDelete