Hi everyone,

I'm trying to accomplish the following; I need to create 2 subprocesses and each subprocess should create a process of their own.

Should look like this:

I'm child xxxx parent xxxx
I'm the subchild xxxx parent xxxx
I'm the second child xxxx parent xxxx
I'm the second subchild xxxx parent xxxx

So far I have this

#include <stdio.h>

int main()
{
    int pid;
    pid = fork();
    if (pid) {
	printf("I'm the parent %d\n", getpid());
    } else {
        printf("I'm the child %d parent %d\n", getpid(), getppid());
	pid = fork();
	if (pid) {

        } else {
		printf("I'm the subchild %d parent %d\n", getpid(), getppid());
        }
    }
    return 0;
}

The above creates a child process and another process but for some reason it does not get the PPID from the child it's been created from. I wonder why is this.

The current output looks like:

I'm the parent 6213
I'm the child 6214 parent 6213
I'm the subchild 6215 parent 1

The subchild's parent should be 6214. Some help would be greatly appreciated

Dani AI

Generated

Short answer: the grandchild shows parent 1 because its immediate parent exited before the grandchild printed, so the kernel re-parents the orphan to PID 1 (init). pointed this out correctly; see the fork(2) manual for the re-parenting behavior: fork(2) — Linux manual page.

How to fix it reliably:

  • Keep the immediate parent alive until its child (the grandchild) has finished. That means each first-level child should wait for its own child, and the original parent should wait for both first-level children. Use waitpid(child_pid, NULL, 0) to wait for a specific child rather than a blind wait(NULL), which is what suggested in principle; see waitpid(2).
  • If you need strict ordering or robust synchronization between processes, use a small IPC primitive (pipe, semaphore, or a condition via a pipe) so the child only exits after the grandchild signals completion.
  • Note the double-fork (daemon) pattern intentionally causes re-parenting; avoid that if you want the child to remain the parent of the grandchild.

Other practical notes:

  • stdio is buffered across forks; mix of buffered printf and process termination can make output look out of order. Explicitly fflush(stdout) after prints (or use write(2)/stderr) to make observed output deterministic: fflush(3).
  • If you want a child to be killed automatically when its parent dies (rather than be re-parented), consider prctl(PR_SET_PDEATHSIG, SIGTERM) in the child — supported on Linux: prctl(2).

In short: the observed PID 1 is expected; fix it by keeping the parent alive until its descendants finish (use waitpid or explicit IPC), and flush output to avoid misleading prints. This keeps parent/child relationships visible as you expect.

Recommended Answers

All 7 Replies

Notice parent 1 . Process with pid 1, aka init, besides other things, adopts every orphan. This means that by the time 6215 prints its message, 6214 is already dead.

Yes I noticed that from the output, and so would any process derived from there as well. How can I fix this?

You have to make the parent wait for the child to die before killing itself. A simple solution will be to use wait(NULL) in the parent

Now the parent waits for the child to die before terminating

int main()
{
    int pid;
    pid = fork();
    if (pid)
    {
                printf("I'm the parent %d\n", getpid());
                wait(NULL);
                printf("The child has died\n");
    }
    else
    {
                printf("I am the child\n");
    }
    return 0;
}

You have to make the parent wait for the child to die before killing itself. A simple solution will be to use wait(NULL) in the parent

Now the parent waits for the child to die before terminating

int main()
{
    int pid;
    pid = fork();
    if (pid)
    {
                printf("I'm the parent %d\n", getpid());
                wait(NULL);
                printf("The child has died\n");
    }
    else
    {
                printf("I am the child\n");
    }
    return 0;
}

Yeah! i was to reply the same...

Very good answer....

Yeah that's interesting, I also did it some other way which basically does what I want but only creates one child and a subchild. I need a second child and a subchild for this second child.

#include <stdio.h>
#include <unistd.h>

int main(void) {
	int pid;
	pid = fork();
	if (pid == 0) { // Child process
		printf("I'm the child %d parent %d\n", getpid(), getppid());
		pid = fork();
		if (pid == 0) { // Subchild process
			printf("I'm the subchild %d parent %d\n", getpid(), getppid());
		}
	}
	wait();
	return 0;
}

I'm trying to start a new process but I'm stuck there, it does the whole thing twice and output isn't right

When you fork for the second time, the parent is not waiting. Also only the parent should wait (See my example above)

Just finished the code, got it working the way I wanted to. Take a look and now maybe it will make sense what I was trying to do

#include <stdio.h>

int main(void) {

	int pID;

	pID = fork();
	if (pID == 0) { // First Child Process
		printf("I am the child %d parent %d\n", getpid(), getppid());
		
		pID = fork();
		if (pID == 0)
			printf("I am the subchild %d parent %d\n", getpid(), getppid());
	}
	else {
		pID = fork();
		if (pID == 0) { // Second Child Process
			printf("I am the second child %d parent %d\n", getpid(), getppid());
		pID = fork();
		if(pID == 0)
			printf("I am the second subchild %d parent %d\n", getpid(), getppid());
		}
	}	
	return 0;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.