Monitoring if process terminated in C

Introduction

I am writing a C monitoring program that executes a fork() and exec() loop. However, I need to check whether the child process has completed or not, without blocking the main process, that is, the monitoring program. Something like that:

Main process

 pid_t child_pid = fork(); if (child_pid == 0) exec(bar); while (1) { if (the child process has finished) foo(); else bar(); } 

What i tried

Given the fact that I have a child pid, I tried the following:

  • Making a kill call with signal 0 and checking errno :

    if (kill(child_pid, 0) == -1 || errno == ESRCH) , which, I think, is not a good way to track the status of a child process, given that it is not safe from the race conditions. Moreover, it did not work, or at least it seemed so.

  • Check with stat(2) whether proc/child_pid . All the above negative arguments are true, and in this case, plus that this method is slower.

  • waitpid(2) . Unfortunately, it blocks the main process.

Question

Is there any other way to get such information? Or maybe I missed something from the solutions that I have already tried?

+7
c process fork monitoring
source share
4 answers

If you pass WNOHANG before waitpid , it should not be blocked.

 if(waitpid(child_pid, &status, WNOHANG) != 0) { // child process has finished foo(); } else { // child process still running bar(); } 
+12
source share

When the process ends, you can configure the parent process to receive and process the SIGCHLD signal, see signal (7) ; the signal handler can only call functions that support the asynchronous signal or set the volatile sigatomic_t flag checked outside the handler (for example, in the main event loop around poll (2) ...), or write (2) in some file descriptor (for example, a channel or some kind of eventfd (2) ). As Bruce Ediger answered , you can also use Linux signalfd .

Then you can use some wait function, for example. waitpid (2) (possibly with WNOHANG if you don't want to block) or wait4 (2) to wait for the process and get its status, etc.

See also Linux Advanced Programming . He has several chapters on these issues.

+11
source share

If you want your process to not be blocked, or perhaps you have other file descriptors to check, you should consider signalfd () if you are writing for Linux.

This system call returns a special file descriptor that you can use in the select() , poll() and epoll() system calls. Having properly configured, the child process exiting forces the kernel to make a special readabl file descriptor. Reading from a special file descriptor gives you a populated structure with information about the exit status of the child process.

+6
source share

The answer of Basil Starinkevich covers the most common situations.

If you have more unusual situations, it is sometimes useful to use a pipe. Before creating a child process, create a pipe using the pipe system call. After creating the child process, close the end of the record in the parent process. Reading from the pipe will be blocked until the child is completed.

This differs from waitpid following ways:

  • Reading from the feed will wait for the child process and all its children to complete (unless some of them close the file handle before).
  • It is possible that several processes are being read from the same file descriptor, making them all wait for the completion of one process (or processes).
  • You are not limited to just waiting for the child to expire. Using this method, you can also wait until the completion of the parental or marriage.
  • Using close on exec, you can wait for the process to complete or the execve system call to complete successfully.
  • You can use the select or poll system call on the handset along with other file descriptors.
+5
source share

All Articles