17979

C++: Timeout for an external application call

Question:

For a c++ program I'm working on, I have to call an external application to do some operations. I can't modify the application. This operations may take too much time so I have to add a timeout. I tried using system() and boost threads

int main() { [...] boost::thread t(function1); t.timed_join(boost::posix_time::seconds(10)); [...] return 0; } void function1() { system("external application"); }

but when I return to the main 10 seconds later, the external application is still running in background. Using exec() instead of system() nothing works because I "lose" the main. What can I do? I'm on Linux.

Answer1:

Use <a href="http://man7.org/linux/man-pages/man2/fork.2.html" rel="nofollow">fork(2)</a>, <a href="http://man7.org/linux/man-pages/man2/execve.2.html" rel="nofollow">execve(2)</a>, <a href="http://man7.org/linux/man-pages/man2/waitpid.2.html" rel="nofollow">waitpid(2)</a> instead of system (which internally uses these syscalls). Read <a href="http://advancedlinuxprogramming.com" rel="nofollow">Advanced Linux Programming</a> which explains the <em>tricky</em> details.

You could want to use <a href="http://man7.org/linux/man-pages/man2/setrlimit.2.html" rel="nofollow">setrlimit(2)</a> in the child. Or in the parent <a href="http://man7.org/linux/man-pages/man2/kill.2.html" rel="nofollow">kill(2)</a> the child (first with SIGTERM, then with SIGKILL) on timeout.

You may want the child to make its own process group using <a href="http://man7.org/linux/man-pages/man2/setpgid.2.html" rel="nofollow">setpgid(2)</a> or setpgrp, then kill the entire process group with <a href="http://man7.org/linux/man-pages/man2/killpg.2.html" rel="nofollow">killpg(2)</a>. This would kill both the child and any command it has started (unless these create there own process groups themselves).

You could handle the SIGCHLD signal (see <a href="http://man7.org/linux/man-pages/man7/signal.7.html" rel="nofollow">signal(7)</a>) using <a href="http://man7.org/linux/man-pages/man2/sigaction.2.html" rel="nofollow">sigaction(2)</a>. SIGCHLD would notably be sent when the child process terminates.

Answer2:

If you want to use <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html" rel="nofollow">exec</a> you first have to <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html" rel="nofollow">fork</a> a new process with does the actual exec. Then after the timeout you can simply <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/kill.html" rel="nofollow">kill</a> the child process. (And for the last you might want to read about <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" rel="nofollow">signals</a>.)

Recommend

  • File path or file descriptor for ARM execute system call
  • SIGCHLD causing segmentation fault, not going into handler
  • Parent trying to read children exit status (or return value), fork and wait
  • Dynamic loose source routing in IP networks
  • Pipe method keeps failing on the parent process
  • protect a shared memory segment with semaphore does not work
  • Why passing char as parameter to islower() does not work correctly?
  • C++: Timeout for an external application call
  • checking process in linux without using top and ps command [closed]
  • can't get input after first time in do while
  • boost socket example stuck in while loop
  • How to wait for all the children to terminate before the parent moves on?
  • Converting millisecond UTC to Human Readable Date_Time
  • Return Code on failure. Positive or negative?
  • measure elapsed time, amount of memory and cpu used by the extern program
  • Fork in Perl not working inside a while loop reading from file
  • PHP syntax highlighting for .html files in Brackets.io Editor
  • Debug application as a different user in VS2008
  • 400 error when downloading file from sharepoint rest api
  • Interpreting STRACE output - pipes and forks
  • Portable JRE on Linux - possible?
  • How to retrieve information from antrun back to maven?
  • How to run “Deployd” on port 80 instead of port 5000 in webserver.
  • Google Custom Search with transparent background
  • Android fill_parent issue
  • How to install a .deb file on a jailbroken iphone programmatically?
  • Repeat a vertical line on every page in Report Builder / SSRS
  • Illegal mix of collations for operation for date/time comparison
  • How to apply VCL Styles to DLL-based forms in Inno Setup?
  • ActionScript 2 vs ActionScript 3 performance
  • How can I estimate amount of memory left with calling System.gc()?
  • Apache 2.4 - remove | delete | uninstall
  • retrieve vertices with no linked edge in arangodb
  • EntityFramework adding new object to nested object collection
  • Checking variable from a different class in C#
  • How can I use `wmic` in a Windows PE script?
  • failed to connect to specific WiFi in android programmatically
  • How to push additional view controllers onto NavigationController but keep the TabBar?
  • How can I use threading to 'tick' a timer to be accessed by other threads?