Why child_1 will print before parent? - c

I have a C code that a parent process will fork() a child process:
int main(){
pid_t child_1;
child_1 = fork();
if (child_1 > 0){
printf("Parent: (PID %d)\n", getpid());
wait(NULL);
}
else if (child_1 == 0){
printf("child: %d", getpid());
}
}
And the output is:
Parent: (PID 1234)
child: 1235
But if I removed the \n in the printf of parent, the output would become:
child: 1235Parent: (PID 1234)
I'm not sure why and I've tried on different OS and the output is the same. Thanks in advance.

printf is line buffered. Which means it won't actually output until a newline is encountered or an explicit flush is done (such as when the process exits). So in your case removing the newline changes when the parent process actually outputs. Since the parent waits for the child to exit it means the parent flush will occur after the child has outputted.

Related

kill(pid,SIGTERM) terminates child process, although pid is of parent

I'm learning about process allocation.
Take this code block for example:
int main(){
pid_t pid = fork();
if(pid == 0){
while(1)
printf("Child ");
} else {
for(int i = 0; i<1000;i++)
printf("Parent ");
kill(pid,SIGTERM);
printf("\n%d \n ", pid);
}
}
pid = 0 is the child process, pid > 0 is the parent process. kill(pid,SIGTERM) is executed by the parent with it's own pid, yet it kills the child and not itself. Why?
As #Siguza mentioned in the comments, you should re-read the documentation of fork. fork returns a positive value of pid to the parent process. That value is the PID of the child process. Therefore, kill(pid, SIGTERM) sends the signal to the child and not the parent.

Where did the zombie process go?

int main() {
pid_t pid;
printf("Parent: %d\n", getpid());
pid = fork();
if (pid == -1) {
perror("fork");
goto clean_up;
} else if (pid > 0) {
sleep(3);
} else {
printf("Child Parent: %d\n", getppid());
printf("Child: %d\n", getpid());
printf("Exiting...\n");
}
clean_up:
return 0;
}
I wanted to create zombie process on purpose (of course for experimenting/learning). After the child exits, the parent doesn't wait()s for the child. So, I'm expecting zombie to show up, in ps -ef | grep zombie.o. But for some reason it is not showing up. What could be the possible reasons?
When the parent exits, all its children (alive or zombie) are assigned PID 1 as their new parent. See the _exit(2) man page: " any children of the process are inherited by process 1".
PID 1 is normally the init daemon, and if it's working properly then it should always wait() for its children. So zombie children will be reaped immediately, and children that are still running will be reaped as soon as they exit.
If you want to create a long-lived zombie, the parent needs to remain alive but not calling wait().

fork() and parent/child process ids

I am a bit confused about why the child process in the following two programs is showing different parents ids.
First program:
int main ( void ) {
int pid, fpid, ppid;
fpid = fork ();
pid = getpid();
ppid = getppid();
printf ("fpid is %d\n", fpid);
sleep(5);
if (fpid > 0){
printf ("\nThis is Parent. My pid %d. My parent's pid %d\n",pid,ppid);
}
else if (fpid ==0){
sleep(1);
printf ("\nThis is Child. My pid %d. My parent's pid %d\n",pid,ppid);
}
else
printf ("fork failed\n");
return (0);
}
Output:
fpid is 53560
fpid is 0
This is Parent. My pid 53559. My parent's pid 44632
MacBook-Pro:~/Desktop/$
This is Child. My pid 53560. My parent's pid 53559
Second program:
int main ( void ) {
int pid, fpid, ppid;
fpid = fork ();
printf ("fpid is is %d\n", fpid);
sleep(5);
if (fpid > 0){
pid = getpid();
ppid = getppid();
printf ("\nThis is Parent. My pid %d. My parent's pid %d\n",pid,ppid);
}
else if (fpid ==0){
sleep(1);
pid = getpid();
ppid = getppid();
printf ("\nThis is Child. My pid %d. My parent's pid %d\n",pid,ppid);
}
else
printf ("fork failed\n");
return (0);
}
Output:
fpid is is 53635
fpid is is 0
This is Parent. My pid 53634. My parent's pid 44632
MacBook-Pro:~/Desktop$
This is Child. My pid 53635. My parent's pid 1
I understand that process 1 is the process that takes over as a parent once the original parent terminates. I guess what I want to know is: isn't the parent process being finished before the child process can process its printf in both cases? Shouldn't the outputs be the same?
Since parent and child processes run concurrently, the order of execution depends on runtime. One of them can finish earlier. When parent finishes before child reaches its getppid(), child process would be adopted by init. Hence the parent id 1.
To see child's actual parent process id:
Let the parent wait for its child termination using wait() or waitpid(), or
Let parent sleep for some perceivable amount like sleep(120) after 'This is parent' printf().
isn't the parent process being finished before the child process can process it's printf in both cases?
Very likely so, but not absolutely certain. You cannot ensure that by sleep()ing for any length of time.
Shouldn't the outputs be the same?
They could be the same, but they are unlikely to be. It's important to note when in each program getppid() is called. The parent process ID reported is the one that applied at the time of the call; it is not necessarily still applicable later, when the value is printed.

Tracing the execution of a process

I have this code that gets its process ID and its parent process:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(){
int pid;
printf("I am the original process with PID %d and PPID %d. \n", getpid(), getppid());
pid = fork();
if (pid >0){
printf("I am the original process with PID %d and PPID %d \n", getpid(), getppid());
printf("My child’s pid is %d \n" , pid);
}
else if(pid == 0) {
printf ("I am the original process with PID %d and PPID %d \n", getpid(), getppid());
}
else if (pid == 1){
printf ("Error – no child process was created \n");
}else{
printf ("Error – system error \n");
}
printf (" PID %d terminates \n", getpid()); /* both processes execute this instruction */
return 0;
}
OUTPUT
I am the original process with PID 1009 and PPID 964.
I am the original process with PID 1009 and PPID 964
My child’s pid is 1010
PID 1009 terminates
I am the original process with PID 1010 and PPID 1009
PID 1010 terminates
Few questions that confuses me..
how does this code is executed?
In the output, you can see that it runs the code under under if(pid == 0) while the condition if(pid > 0) is already executed. how come pid is equal to 0? while it was set already to greater than 0.
Lastly , what does fork() really do?
fork() makes multiple processes, or a "child". So the parent and child execute the code. The parent's pid is > 0 and the child's is ==0.
So, the parent and child execute at similar times starting at the fork command. So let's start with the parent. The parent checks the first statement (pid > 0) and finds it is true, so it prints out the two statements. Then it goes all the way to the print statement after the last else.
Now to the child. The child checks the first if statement, and is false. Checks the next (pid == 0) and finds it is true. So now it's going to print out that statement. Now it will skip to the print statement after the else and prints again.
Note: The parent and child can execute at different times, so if you run the code multiple times the output may be in a different order.

c - printf c issues in terminal

I have the following code in my main:
//testing with fork
printf("I am process: %d\n", getpid());
pid_t pid = fork();
printf("Now I am process: %d\n", getpid());
printf("fork returned %d\n", pid);
if(pid == 0){
printf("I am child %d\n", getpid());
}
However the output on my terminal gives me this:
terminal output pic
I run my program with a param of 'config_file.txt' as you can see on the first line, and the rest of it prints out fine until it hits the fork, and my cmd line comes up in between it...any ideas on why that is or how I can fix it? Is there something wrong with the code? I was just following a simple forking tutorial.
Edit: Also, after running it my program hangs there, and I have to hit enter to get my cmd line back up.
What's happening is that the parent process is finishing before the child process. When the parent finishes the prompt is displayed, however since the child is still running it continues to print output to the console.
If you want the parent to wait until the child is done, use the wait() function:
printf("I am process: %d\n", getpid());
pid_t pid = fork();
printf("Now I am process: %d\n", getpid());
printf("fork returned %d\n", pid);
if(pid == 0){
printf("I am child %d\n", getpid());
} else {
wait(NULL);
}

Resources