Ok, this is a bit of a thorny problem. I need to launch a backgrounded process that will (1) wait N secs, and then (2) execute some command. Additionally, I need to capture the pid of the background process itself, because when the parent process finishes it will kill the backgrounded process if necessary. It looks a bit like this in shell syntax:
(sleep 15 && run_some_cmd) & # launch bg process
b开发者_如何学Cg_pid=$! # capture the bg pid
# do some stuff here...
kill -9 $bg_pid # and kill the bg_pid if necessary
So that's the launch in shell. However, I'm trying to do this in Python. The tricky thing is that since I need to capture the bg pid, I can't use os.system() or os.fork(), since in each case the parent process does not have access to the pid of the child. I'm trying to get it to work with subprocess.Popen(), but it's a bit tricky given the "sleep 15" portion.
Any ideas?
I can't use os.system() or os.fork(), since in each case the parent process does not have access to the pid of the child.
Er, the parent gets the pid as a return value from fork()
.
In any case, I would suggest using the subprocess module. It gives you access to the pid via the pid
attribute of the Popen object. You can use the os.kill() function to send a signal to a process (to kill it).
Originally, I included a comment to the effect of "subprocess is preferable because it works on windows and fork() doesn't". This was removed almost immediately, because while the subprocess module works, os.kill() doesn't. However, you can work around this by defining a kill function for Windows, as well, as suggested here and (somewhat ironically) by Alex Martelli himself here. So now I can in fact declare that subprocess has the advantage of being more cross-platform, and this makes it somewhat cool.
Of course, if you use Alex Martelli's answer for this question, the ability to run on Windows is reduced again, as you're relying on features of the system shell (cygwin always is an option, of course).
When you give shell
as True
to subprocess.Popen
, the command you execute can be the same as you're executing directly in the shell in your example, i.e., (sleep 15 && run_some_cmd)
should be fine.
精彩评论