Thread: Checking if a process has terminated?

  1. #1
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654

    Checking if a process has terminated?

    I am confused here.

    What I want to do is checking if a child process has terminated or if it is still running.
    Basic, right? Well, it seems not so much.

    First research seems to indicate that using waitpid can achieve this. It is important to note that I do not want to wait until a process has exited, but merely check if it has (and remove zombie processes).
    The manual says that by checking the status with WIFEXITED, I should know if a process has exited by means of a return statement or exit function (at least to a degree).
    Now, this confuses me since this...

    Code:
    waitpid(child, &status, (background ? WNOHANG : 0));
    printf("WIFEXITED: %d, WEXITSTATUS: %d, WIFSIGNALED: %d, WTERMSIG: %d, WCOREDUMP: %d, WIFSTOPPED: %d, WSTOPSIG: %d, WIFCONTINUED: %d",
    	WIFEXITED(status), WEXITSTATUS(status), WIFSIGNALED(status), WTERMSIG(status), 0/*WCOREDUMP(status)*/, WIFSTOPPED(status),
    	WSTOPSIG(status), WIFCONTINUED(status));
    (background = true)
    ...doesn't seem to work. WIFEXITED seems to be set to 1, even though the process is still running.
    I can easily verify this by running ps.

    So I thought about using waitid. Unfortunately, for some reason (perhaps the system I am using is outdated?), the siginfo_t structure and P_PID constant are undeclared in the headers (well, I tried including them, but gcc is giving me errors). So that didn't work either.

    So color me confused. How do I figure out if a child has terminated and remove it as a zombie process? It doesn't matter if it exited normally or some abnormal means. Both should be detected.

    Any information would be welcome.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Are you running ps and then calling waitpid()? A terminated process will still show up in the process list UNTIL someone calls waitpid() on it. Run ps again after calling waitpid(), the process should be gone. A terminated but not yet waited-for process is in "zombie" state ('Z')

    EDIT: Hmm. Looks like you probably understand that. What state IS the child in?
    Last edited by brewbuck; 11-19-2011 at 01:13 PM.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by brewbuck View Post
    EDIT: Hmm. Looks like you probably understand that. What state IS the child in?
    Just running. Or so I hope.
    I tested by created a test process (the process is spawned by the process that checks for it to terminate) that simply does

    sleep(60);

    The process shows as running before and after the waitpid call.
    If it's a zombie process, it usually marks them as "degenerate" in the ps command output.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    What's the return of waitpid? If that doesn't equal child (or is greater than 0 if child is one of the wildcard values) there's no point trying to make sense of status.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Ah. It returns 0, which according to the manual seems to indicate that the process whose status I am trying to query has not changed any state - IE has not quit.
    Mistakes are trivial when you are still a beginner to things. You helped me out greatly, so many thanks.

    Although, a question remains. Does checking for the return of waitpid == child && WIFEXITED capture the case if the process exited for some (abnormal) reason?

    EDIT: It appears it does not. So what is the best way? Simply checking for all types of flags?
    Last edited by Elysia; 11-19-2011 at 03:53 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    if I were you, I would look into signal() or sigaction(). they are the means by which unix/linux notify the parent process that something has happened to the child. you can get the child's return code and the signal (if any) that terminated the child. signal()/sigaction() handlers are not C++ exception safe, just so you know.
    Last edited by Elkvis; 11-21-2011 at 08:46 AM.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Well, the assignment requires me to both normal polling and signalling. So yes, I have looked into signals.
    Actually, I do believe I've solved this sometime before. I found a number of problems and fixed them, and so got the polling to work reliably.
    Now trying to get signal handlers to work, but still haven't been able to detect terminated processes that way. But I will find a way in due time.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    what problems are you experiencing with detecting terminated processes using signals?

    EDIT: just wanted to note that this was my post #666 \m/
    Last edited by Elkvis; 11-21-2011 at 09:28 AM.

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I don't get any signal when they're killed (SIGKILL).
    (I do get a signal when they terminate properly.)
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    you don't get a signal at all? that's strange. normally you should get a signal any time the child process terminates, stops or continues. you can use the macro WIFSIGNALED(status) to determine if the child was terminated by a signal, where status is the second parameter to waitpid().

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    No signal at all.
    I figured out how to detect killed processes otherwise when polling. That works fine.
    Whenever I get a signal, I simply loop through all the processes and figure out which ones have terminated, just as I would when polling. Only I do when I get a signal instead of all the time.
    Although I do tend to block the signals until it is appropriate to do the polling (to avoid interrupting sys calls and all that).
    It works fine when the child exits normally, though, as I mentioned.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    is it possible that your child process calls fork(), and then terminates? that would leave its child orphaned, and it would not be a child of your original process, and you would not get any signals from it, although I can't see that being a real possibility, given the behavior you mentioned. post some code?

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    No, I explicitly test this by starting a child process that does nothing but sleep, and then killing it with kill.

    Code:
    #ifdef SIGNALDETECTION
    void child_status_change_handler(int signum)
    {
    	puts("Signal recieved!");
    	signum = signum; // Eliminate unused warning
    	check_for_terminated_processes();
    }
    #endif
    
    int main()
    {
    	char buf[2048];
    
    	signal(SIGCHLD, &child_status_change_handler);
    
    	for (;;)
    	{
    		sighold(SIGCHLD);
    		printf("Ready>");
    		fgets(buf, sizeof(buf), stdin);
    		sigrelse(SIGCHLD);
    
    		const char* cmd;
    		const char* arg[5];
    		timeval begin;
    
    		sighold(SIGCHLD);
    		if (!get_command_and_args(buf, &cmd, arg)) goto Error;
    		bool failure = (!handle_command(cmd, arg, &begin));
    		sigrelse(SIGCHLD);
    	}
    }
    I'll start with this. This is not the complete code, but a mini-version of it to provide an overview.
    I may include check_for_terminated_processes later if deemed necessary.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    I'm not sure I understand what's going on with your calls to sighold() and sigrelse(). after reading the reference for sigrelse(), it seems like calling sigrelse(SIGCHLD) would cause you to stop receiving notifications of that signal, but I could easily be misunderstanding. I've never used those functions before.

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    sighold will block the process from receiving signals (different from ignoring them).
    sigrelse will remove this blocking, and the process will the immediately receive any signals waiting.
    In other words, they just make the signal handler doesn't fire when inappropriate.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Process Terminated with status -1073741510
    By Varethien in forum C Programming
    Replies: 5
    Last Post: 08-09-2011, 04:16 AM
  2. Process terminated with status -1073741819
    By smithx in forum C Programming
    Replies: 5
    Last Post: 11-01-2010, 11:13 PM
  3. Checking for child process errors?
    By Blasz in forum C Programming
    Replies: 11
    Last Post: 05-19-2010, 07:41 AM
  4. un-terminated stream
    By WDT in forum Networking/Device Communication
    Replies: 1
    Last Post: 04-01-2005, 07:08 PM
  5. Replies: 5
    Last Post: 03-21-2004, 03:18 PM