Linux, timing out on subprocess
Ok, I need to write a code that calls a script, and if the operation in script hangs, terminates the process.
The preferred language is Python, but I'm also looking through C and bash script documentation too.
Seems like an easy problem, but I can't decide on the best solution.
From research so far:
- Python: Has some weird threading model where the virtual machine uses one thread at a time, won't work?
- C: The preferred solution so far seems to use SIGALARM + fork + execl. But SIGALARM is not heap safe, so it can trash everything?
- Bash: timeout program? Not standard on all distros?
Since I'm a newbie to Linux, I'm probably unaware of 500 different gotchas with those functions, so can anyone tell me what's the safest and cleanest way?
Avoid SIGALRM
because there is not much safe stuff to do inside the signal handler.
Considering the system calls that you should use, in C, after doing the fork-exec to start the subprocess, you can periodically call waitpid(2)
with the WNOHANG
option to inspect whether the subprocess is still running. If waitpid
returns 0
(process is still running) and the desired timeout has passed, you can kill(2)
the subprocess.
In bash you can do something similar to this:
- start the script/program in background with &
- get the process id of the background process
- sleep for some time
- and then kill the process (if it is finished you cannot kill it) or you can check if the process is still live and then to kill it.
Example:
sh long_time_script.sh &
pid=$!
sleep 30s
kill $pid
you can even try to use trap 'script_stopped $pid' SIGCHLD
- see the bash man for more info.
UPDATE: I found other command timeout. It does exactly what you need - runs a command with a time limit. Example:
timeout 10s sleep 15s
will kill the sleep
after 10 seconds.
There is a collection of Python code that has features to do exactly this, and without too much difficulty if you know the APIs.
The Pycopia collection has the scheduler module for timing out functions, and the proctools module for spawning subprocesses and sending signals to it. The kill
method can be used in this case.
精彩评论