LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-05-2008, 10:01 AM   #1
Curtor
Member
 
Registered: Feb 2008
Posts: 65

Rep: Reputation: 16
Finding all your children


I'm currently writing a C++ program that, in short, forks and then the child execs. The parent than waits for the child that exec'ed to die, or quit, or terminate, or whatever, and report on it.

When this happens though, I want to know what happened with any of the other programs that spawned from that exec'ed child. So, if the exec'ed child forked twice and then exited, I want to know that the exec'ed child died (as I would receive a sig child) and that the parent has just inherited 2 new processes.

There is way to get a list of processes on a machine and there is a way to get the parent of the current process. Therefore, as an example, the inefficient way of doing this would be to run the system command 'ps -o pid,ppid ax', look at every ppid, and if it matches the current proccess pid, than it is your child.

I was hoping that there is a better way to do this. Any suggestions besides going through and looking at every process and its ppid?
 
Old 12-05-2008, 11:23 AM   #2
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 111Reputation: 111
Quote:
Originally Posted by Curtor View Post
I'm currently writing a C++ program that, in short, forks and then the child execs. The parent than waits for the child that exec'ed to die, or quit, or terminate, or whatever, and report on it.

When this happens though, I want to know what happened with any of the other programs that spawned from that exec'ed child. So, if the exec'ed child forked twice and then exited, I want to know that the exec'ed child died (as I would receive a sig child) and that the parent has just inherited 2 new processes.
Just call wait() in loop. Optionally with WNOHANG if you need to do other things in the parent besides waiting for children to change status. This way it is not necessary that your parent knows which processes are its child processes.

Another option would be to have a signal-handler for SIGCHLD that sets a global atomic boolean variable which is checked for by your main loop. If it is set call wait(..WNOHANG..) in a loop until no more childs are reported by wait().

If you really want/need the parent process to know which PID's are its child processes, just record all child PID's as returned by fork() in an array or so.

Keep in mind that if your child also fork()s off a subchild (grandchild) and the child exits before the grandchild, it will be the init process that inherits the grandchild, not your parent. This is why just storing the pid's returned by fork will do.

You can verify by compiling and running this:
Code:
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
    pid_t pid;

    pid = fork();
    if (pid) {
        printf("Parent pid: %d\n", getpid());
    } else {
        printf("Child pid: %d\n", getpid());
        pid = fork();
        if (pid) {
            return 0;
        } else {
            printf("Grantchild pid: %d\n", getpid());
        }
    }
    sleep (120);
    return 0;
}
If you take a unique (i.e. easily greppable) name for the exutable (I used "qqq"), you can verify that the subchild has been inherited by init with these commands (you have 2 minutes (120 secs) to run them :-)
Code:
ps -o pid,ppid,cmd ax | grep '[q]qq'
pstree -p | less -p qqq
 
Old 12-05-2008, 01:14 PM   #3
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by Curtor View Post
I'm currently writing a C++ program that, in short, forks and then the child execs. The parent than waits for the child that exec'ed to die, or quit, or terminate, or whatever, and report on it.

When this happens though, I want to know what happened with any of the other programs that spawned from that exec'ed child. So, if the exec'ed child forked twice and then exited, I want to know that the exec'ed child died (as I would receive a sig child) and that the parent has just inherited 2 new processes.

There is way to get a list of processes on a machine and there is a way to get the parent of the current process. Therefore, as an example, the inefficient way of doing this would be to run the system command 'ps -o pid,ppid ax', look at every ppid, and if it matches the current proccess pid, than it is your child.

I was hoping that there is a better way to do this. Any suggestions besides going through and looking at every process and its ppid?

A colleague of mine, Anton Rapp, suggested a very simple and elegant solution - provided children are unaware and not evil.

In the top father process you introduce an environment variable with a funky name.

Since children inherit environment, just look for that environment variable in every process on the machine.

...

And the funky environment variable may have father PID as its value - in case more than one father with the same name runs.

Last edited by Sergei Steshenko; 12-05-2008 at 01:23 PM.
 
Old 12-08-2008, 11:09 AM   #4
Curtor
Member
 
Registered: Feb 2008
Posts: 65

Original Poster
Rep: Reputation: 16
hmm .. interesting.
Quote:
Keep in mind that if your child also fork()s off a subchild (grandchild) and the child exits before the grandchild, it will be the init process that inherits the grandchild, not your parent. This is why just storing the pid's returned by fork will do.
I thought that the parent would inherit it. I'll have to look into this further.
Quote:
If you really want/need the parent process to know which PID's are its child processes, just record all child PID's as returned by fork() in an array or so.
Quote:
In the top father process you introduce an environment variable with a funky name.
Would it be sufficient to, every time you fork, record the child PID and have the child create a new session ID. Then, any grandchild of that child will be in the same session of that child and the parent will have a list of session IDs to check for children. (Granted of course that the grandchildren do not create additional session IDs).
 
Old 12-08-2008, 12:50 PM   #5
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by Curtor View Post
...
Would it be sufficient to, every time you fork, record the child PID and have the child create a new session ID. Then, any grandchild of that child will be in the same session of that child and the parent will have a list of session IDs to check for children. (Granted of course that the grandchildren do not create additional session IDs).
I'm not sure I understand your intent.

Anton's idea was generic and non-intrusive.

I.e. suppose you have even a closed-source application which can spawn children.

Wrap it in a script which does that funky named environment variable stuff, and all your children have it. Kind of auto-attached tag.

The context was what I call "graceful killing" - suppose you have something which launches computer jobs in a network, and you need to kill the job and all its children. And while you are killing them (this is not atomic) they can still spawn other children.

I had a more complex algorithm to achieve that "graceful killing", but Anton's suggestion seems very simple and robust.

Well, I do not know what you need this for - knowing all your children.
 
Old 12-09-2008, 07:00 PM   #6
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
I think the real question is why does the parent need to know about grandchildren exits? I have a similar system in which the main program is always a session leader and it gives every fork a new process group. Through waitpid with -pgid, it monitors that something is still in the original process group and once no process is in a particular group it writes off that particular fork. The child can fork as much as it wants because the process group is inherited, but if a grandchild creates a new session or a new group and everything else in the process group exits then the original program stops IPC (for which the sub-forks will have inherited pipes) and whatever that new session does is outside of the scope of the main program's responsibility. Keep in mind that a group leader can't setsid, so the original forks can never start new sessions in my application*.
ta0kira

*There is a special case I use to allow denial of terminal inheritance by creating a new session for the fork in lieu of a new process group, but that can be used in the same way as a process group when waiting for exits.

Last edited by ta0kira; 12-09-2008 at 08:26 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
how do you create two children using fork() rdtgr Programming 6 12-03-2006 10:18 AM
Protecting my children on my network... rude_reality Linux - Networking 2 11-15-2006 07:45 PM
Any software for children around? lfys Linux - Software 4 11-06-2006 11:05 AM
how do I make the children gone with the parents jpan Programming 6 09-19-2004 11:40 PM
How many children have been created... maniac01 Programming 8 03-11-2004 11:27 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:43 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration