This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Working of fork() in linux gcc
Why does this code print two times?
#include<stdio.h>
main()
{
printf("hello\n");
fork();
}
The above code prints "hello" one time.The code below prints "hello" two times.
#include<stdio.h>
main()
{
printf("hello");
fork();
}
The code above prints "hello" two times.
Please Somebody explain this strange behavior.
It's not guaranteed to behave in this way, but the usual behaviour is: With
printf("hello");
the "hello" is printed to the output buffer, but that buffer is not yet flushed. Then upon the
fork();
the program state is copied to the child process, including the non-empty output buffer. Upon exit, the output buffers of parent and child are both flushed.
With the newline, the output buffer is flushed before the fork().
Related
This question already has answers here:
Why is main called twice?
(3 answers)
Closed 1 year ago.
I encountered this in my school work and it didn't produce what I thought it should:
int main() {
printf("c");
fork();
printf("d");
}
I know there are several things that aren't good about this code (i.e. no parameters in main, no variable for the return value from fork, no return statement at the end, etc.), but this is how it was presented and it's not relevant to my question anyway.
This code produces the output:
cdcd
It was my understanding that when fork is called, both parent and child would resume/begin on the line after the fork call. Based on that, I would have expected the output to be:
cdd
Assuming, of course, that the fork call is successful. Can anyone explain to me why that "c" is printed a second time even though it's on the line before the fork call?
Thanks!
M_MN
You forked your program before flushing stdout (i.e.: data was still in the output buffer). Just call fflush(stdout) to fix it:
❯ cat test.c
#include <stdio.h>
#include <unistd.h>
int main() {
printf("c");
fflush(stdout);
fork();
printf("d");
}
[22:14:01]~/devel
❯ clang test.c -o test
[22:14:07]~/devel
❯ ./test
cdd[22:14:09]~/devel
The reason you're seeing c twice is that the fork() duplicates the unprinted buffered output. You could flush the output stream before the fork():
fflush(stdout);
Or you could set stdout to be unbuffered, but you should do this first, before calling printf() the first time:
setvbuf(stdout, NULL, _IONBF, 0);
Here's what I'm guessing is happening. printf writes to the stream stdout. Since you didn't flush stdout after printing "c" nor did that string end in a new line, the character sat there in a user-space buffer. When you called fork, the child process got a copy of the parent's virtual address space including the buffered text. When both programs exited, their buffers were flushed and so "c" showed up twice.
Try adding fflush(stdout); just prior to the call to fork.
This question already has answers here:
printf anomaly after "fork()"
(3 answers)
Closed 4 years ago.
So as far as i know fork creates a duplicate of the process it's called from but it also copy's it's program counter so it continues from the line after it's called but why is this code printing hello world twice when it's before the fork
#include <stdio.h>
#include <sys/wait.h>
int main()
{
printf("Hello World");
fork();
wait(NULL);
return 0;
}
printf doesn't actually print -- it actually just puts data into a buffer to be printed later. It will actually be printed when the buffer gets flushed, which can happen in a variety of ways.
In your case, the buffer flush doesn't happen until after the fork, so both the parent and the child have a copy of the string to be printed in the buffer when they fork, and both end up printing it.
This question already has answers here:
fork() branches more than expected?
(3 answers)
Closed 8 years ago.
Can anyone, please, explain how does this code work ?
int main()
{
printf("Hello");
fork();
printf("World");
}
Prints:
HelloWorldHelloWorld
My exact question is, why hello is printed twice. Isn't hello printed first, then fork() is executed ?
Also, sometimes it prints:
HelloWorld
// then the reports....process exited with return value 0..etc etc.. then...//
HelloWorld
Why this output ?
The reason is: buffered output. "Hello" is in the buffer but not yet put out when you do the fork, so the forked process starts with the same buffer including the same word "Hello". Then, both the parent and the child output "World" so the total output is "HelloWorld" for both of them.
Adding to #ammoQ answer:
int main()
{
printf("Hello");
fflush(stdout);
fork();
printf("World");
}
will get you to the expected result.
Fork creates a copy of the process. And printf() may be buffered when the fork happens, this buffer would be copied.
Pretty solid explanation here:
fork() branches more than expected?
This question already has answers here:
Working of fork() in linux gcc [duplicate]
(5 answers)
Closed 8 years ago.
I am using gcc compiler on linux.
When I run this code (Notice"\n" is not present after hello world in printf)
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
printf("Hello world");
fork();
}
I GET THIS OUTPUT: Hello worldHello world
On the other hand
When I run this code (Notice"\n" is present after hello world in printf)
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
printf("Hello world\n");
fork();
}
I GET THIS OUTPUT: Hello world
Can someone describe in detail that, why omitting or leaving "\n" prints "Hello world" twice?
To elaborate on the answer in the linked question and relate it to your question, stdout generally buffers input until it sees a \n, or you explicitly fflush it.
When you have the \n there, you are making it flush before the fork().
Without the \n, it flushes after the fork, so it will exist in both processes.
In the linked question, they talk about fflush(), but \n has the same effect of causing stdout to flush.
You will see only one print with the program below as well:
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
printf("Hello world");
fflush(stdout);
fork();
}
Edit: Due to a comment from Dabo, \n will only cause a flush if stdout is in line buffering mode instead of full buffering mode. We can observe in the following program that we still see the string printed twice, even with \n, when full buffering mode is turned on using setvbuf.
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
setvbuf(stdout, NULL,_IOFBF, BUFSIZ);
printf("Hello world\n");
fork();
}
Output:
Hello world
Hello world
Not having the \n means that "hello world" is still in memory - ready to go one its merry way to the terminal.
fork will make a duplicate of this memory - i.e. now you have two processes with the same "hello world" in memory. When the program terminates it will flush this to stdout. I.e. getting it twice.
But if you put the \n in - it gets flush to stdout immediately. Hence this buffer will be empty before the fork is called.
I would say both versions are incorrect. The C runtime will register atexit handlers to flush standard buffers when exit() is called. The proper way to cause your program print only once is to call _exit(0); in child process. This way your child won't call atexit ( which in turn won't flush buffers twice)
if (fork() == 0)
_exit(0);
This question already has answers here:
How do 2 or more fork system calls work?
(4 answers)
Closed 8 years ago.
I have executed the following code :
#include<stdio.h>
int main()
{
printf("hello \t");
fork();
fork();
return 0;
}
Output : hello hello hello hello
Does this mean that fork() create exact copy of the code for the child process as that of the parent process except the fork() call which gets executed is eliminated?
This is confusing me because I studied somewhere that "fork() begins execution from the next line of the code". So, if this is true then it should create 3 child processes and 1 parent process and should print "hello" only once.
Please resolve this .
I ran this code on gcc compiler.
That's because the string "hello" was stored in the output buffer of the parent process.
printf flushes the buffer when it meets \n, otherwise it prints the output string only if the buffer is full.
By default, the child process inherits the buffer of parent process, so if the buffer is not flushed, the buffer of child process also contains "hello".
if :
#include<stdio.h>
int main()
{
printf("hello \n");
fork();
fork();
return 0;
}
You will see only one "hello".
This is because of printf... u say use printf("hello \n") in order the buffer is flushed after a newline or u can use fflush(stdout) in u r code and the output will be just one hello...