Why fork is executing the program twice from start???
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Why fork is executing the program twice from start???
Hi,
I am learning about OS and I wrote this simple forking program...
Here's the code..
Code:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
pid_t pid;
printf ("\n\n~~~~~~~~~~~~At the start of the programm..... My pid = %d and my parent id = %d", getpid(), getppid());
pid = fork();
printf ("\nforked done my pid = %d and my parent pid = %d\n", getpid(), getppid());
if (pid < 0)
{
fprintf (stderr, "Fork Failed");
return -1;
}
else if (pid == 0)
{
printf("\n\nhello i am a child process my pid = %d and my parent pid = %d\n", getpid(), getppid());
}
else
{
wait(NULL);
printf ("\n\nWait Complete my pid = %d and my parent pid = %d\n", getpid(), getppid());
}
return 0;
}
Now the problem is, first statement - At the start of the programm..... is being printed twice!!!!!
Here's the final output
Code:
mankaj@mankaj:~$ cc new2forking.c -o new2forking
mankaj@mankaj:~$ ./new2forking
~~~~~~~~~~~~At the start of the programm..... My pid = 4239 and my parent id = 1762
forked done my pid = 4239 and my parent pid = 1762
~~~~~~~~~~~~At the start of the programm..... My pid = 4239 and my parent id = 1762
forked done my pid = 4240 and my parent pid = 4239
hello i am a child process my pid = 4240 and my parent pid = 4239
Wait Complete my pid = 4239 and my parent pid = 1762
mankaj@mankaj:~$
How can it print the first statement, that is BEFORE the fork() statement twice????
I am really confused. What am I doing wrong? Or is it suppose to be this way?
I am running Natty 11.04 btw..
Thanks a lot for your help
Click here to see the post LQ members have rated as the most helpful post in this thread.
Yes this is really confusing... but try editing the first printf, add a "\n" at the end, like this:
printf ("\n\n~~~~~~~~~~~~At the start of the programm..... My pid = %d and my parent id = %d\n", getpid(), getppid());
You won't get the message repeated twice. That's because a printf without a "\n" accumulates the characters in a buffer. Then, the fork clones the buffer itself along with the whole process.
Finally, as soon as the buffer is emptied (because of a "\n" in your case), then all messages are printed out, the old ones along with the new ones.
Yes this is really confusing... but try editing the first printf, add a "\n" at the end, like this:
printf ("\n\n~~~~~~~~~~~~At the start of the programm..... My pid = %d and my parent id = %d\n", getpid(), getppid());
You won't get the message repeated twice. That's because a printf without a "\n" accumulates the characters in a buffer. Then, the fork clones the buffer itself along with the whole process.
Finally, as soon as the buffer is emptied (because of a "\n" in your case), then all messages are printed out, the old ones along with the new ones.
Oh my GOD!!!
I can't believe that!!! How in the world you knew that??? lol I mean that is Soooo Not Obvious!!!
Thanks a ton. I kept looking at the program for so long....had no clue what to do...
Is there anything else that I "should" be aware of, such obsure stuff that you won't expect to happen!!!!??
Thanks a lot....you saved tons of hours for me....
Ok how about this.... i have only removed the \n at the end of the bolded line...
Code:
int main()
{
pid_t pid;
printf ("~~~~~~~~~~~~At the start of the programm..... My pid = %d and my parent id = %d", getpid(), getppid());
pid = fork();
printf ("\n\nforked done my pid = %d and my parent pid = %d", getpid(), getppid());
And the output is
Code:
mankaj@mankaj:~$ cc new2forking.c -o new2forking
mankaj@mankaj:~$ ./new2forking
~~~~~~~~~~~~At the start of the programm..... My pid = 3077 and my parent id = 2948
~~~~~~~~~~~~At the start of the programm..... My pid = 3077 and my parent id = 2948
forked done my pid = 3078 and my parent pid = 3077
hello i am a child process my pid = 3078 and my parent pid = 3077
forked done my pid = 3077 and my parent pid = 2948
Wait Complete my pid = 3077 and my parent pid = 2948
Why the order has changed? What \n makes the buffer empty? First \n or last \n of a printf statement? I didn't get this part...
Oh my GOD!!!
I can't believe that!!! How in the world you knew that??? lol I mean that is Soooo Not Obvious!!!
Thanks a ton. I kept looking at the program for so long....had no clue what to do...
Is there anything else that I "should" be aware of, such obsure stuff that you won't expect to happen!!!!??
Thanks a lot....you saved tons of hours for me....
The old guy looks at you with a brief, dumbfounded stare, but quickly recovers. He pushes himself back from the desk in his cube and leans forward, pointing to a slightly rough spot on his now-glistening cranium. "Believe it or not, young'un, at one time way back then I still had hair, and that spot right there is where I yanked quite a bit of it out ... (little did I know at the time how much I'd miss it) ... solving a problem that's almost exactly like yours." He cracks a surprisingly youthful smile. "And that is why I spend a part of my day, every day, on linuxquestions.org."
The old guy looks at you with a brief, dumbfounded stare, but quickly recovers. He pushes himself back from the desk in his cube and leans forward, pointing to a slightly rough spot on his now-glistening cranium. "Believe it or not, young'un, at one time way back then I still had hair, and that spot right there is where I yanked quite a bit of it out ... (little did I know at the time how much I'd miss it) ... solving a problem that's almost exactly like yours." He cracks a surprisingly youthful smile. "And that is why I spend a part of my day, every day, on linuxquestions.org."
Why the order has changed? What \n makes the buffer empty? First \n or last \n of a printf statement? I didn't get this part...
Thanks a lot..
I think this depends on the specific implementation of the printf, depending on your version of C... I bet the buffer usually flushes at the last "\n" of a printf call.
The order in which you see the prints from the processes also depends on the scheduler, so it can't be considered reliable.
Quote:
Is there anything else that I "should" be aware of, such obsure stuff that you won't expect to happen!!!!??
Well, the answer is difficult, so I can only suggest reading a good book... I found this reference on how a fork should behave on the web, this seems quite explanatory: http://pubs.opengroup.org/onlinepubs...ions/fork.html
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
pid_t pid;
printf ("\n\n~~~~~~~~~~~~At the start of the programm..... My pid = %d and my parent id = %d", getpid(), getppid());
At this point, before forking, you need to make sure all pending output is output. Add
Code:
fflush(stdout);
fflush(stderr);
to explicitly flush both standard output and standard error streams.
Quote:
Originally Posted by mayjune
How can it print the first statement, that is BEFORE the fork() statement twice????
At fork() time, all memory structures are duplicated. This includes any data pending in output buffers. Since the statement was in the output buffer for standard output (as noted by civic, above), both processes will include the first statement in their output when they finally flush the buffers.
Add explicit fflush() for each open output stream before fork() calls to avoid this situation.
Last edited by Nominal Animal; 05-28-2011 at 09:14 PM.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.