Questions on fork() [duplicate] - c

This question already has answers here:
printf anomaly after "fork()"
(3 answers)
Closed 8 years ago.
I am trying to understand fork(), and so I put together the following example:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
void main()
{
if(fork()==0)
{
printf("2");
if(fork()==0)
{
printf("4");
}
else
{
printf("3");
}
}
else
{
printf("1");
}
}
When I was tracing this on paper, I drew the following sketch:
So I believe the output should be 1234. However, when I run this code, the output is 12324. Why is that? Where is my mistake?
Update:
After reading the comments, it was suggested to do any of the following
Add \n to each printf statement
OR: Add fflush(stdout); after each printf statement
OR: Add setbuf(stdout, NULL); <---- this is what I ended-up doing :)
After updating my code, the output was indeed 1234.

printf() output is usually line-buffered. So when you fork(), the new processes gets the copy of the buffer as well. When the process exits, the whole buffer is flushed (or anytime it's flushed in the code or whenever the buffer becomes full). Hence, you see a copy of printf's output one more time.
1) You can flush it after each printf() call by using fflush(stdout);
2) or using \n for example:
printf("2\n");
Another way is to disable the buffering with:
setbuf(stdout, NULL);

Your analysis is almost correct. However, printf does not necessarily write immediately do file descriptor - output is buffered inside the process. The second process does fork after putting 2 in the buffer. Both second and third processes will have it in the buffer and print 2.
If you do printf("2\n") instead new line character will force printf to flush the buffer and you will see only one 2.

Related

Unexpected output on a fork call in C [duplicate]

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.

Where does fork() start from [duplicate]

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.

What happens if I call fork() inside main? [duplicate]

This question already has answers here:
Working of fork() in linux gcc [duplicate]
(5 answers)
Closed 9 years ago.
Simple piece of code:
#include <stdio.h>
#include <string.h>
main()
{
printf("Process");
fork();
fork();
return 0;
}
From my understanding of fork(), after this code executes we will have 3 child processes and 1 parent process. Also whenever we call fork() the execution should start from the statement immediately after the fork() statement. Hence according to me "Process" should be printed only once. But in my output Process is being printed 4 times. How is that possible?
Because the standard output is line buffered by default, when you call fork(), the output buffer is inherited by all the children processes.
There are several different ways to change this behavior:
Add a new line character at the end:
printf("Process\n");
or call fflush() to flush the output:
printf("Process");
fflush(stdout);
or change standard output to not buffered using setbuf() or setvbuf():
setbuf(stdout, NULL);
printf("Process");
Using either way, you'll see the output only once.
Note: see #Dvaid Schwartz's answer for the bug with calling atexit() multiple times in your code.
Your program has a bug. All the children return from main, causing atexit handlers to run four times. The children should call _exit.
Here's how your code should look:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
main()
{
int is_child = 0;
printf("Process");
if (fork() == 0)
is_child = 1;
if (fork() == 0)
is_child = 1;
if (is_child)
_exit(0);
return 0;
}

Why is the line following printf(), a call to sleep(), executed before anything is printed?

I thought I was doing something simple here, but C decided to go asynchronous on me. I'm not sure what's going on. Here's my code:
#include <stdio.h>
int main() {
printf("start");
sleep(5);
printf("stop");
}
When I compile and run, I notice that sleep(5) works like a charm. But the compiler decided it was a good idea to skip the first printf() and go out of order, so when running, the program waits for 5 seconds and then prints startstop.
What's the deal? My theory is that the program initiates the print operation with the shell, then continues with the program, leaving Bash to wait until the program is no longer busy to actually render the strings. But I really don't know.
Thanks
printf uses buffered output. This means that data first accumulates in a memory buffer before it is flushed to the output source, which in this case is stdout (which generally defaults to console output). Use fflush after your first printf statement to force it to flush the buffered data to the output source.
#include <stdio.h>
int main() {
printf("start");
fflush(stdout);
sleep(5);
printf("stop");
}
Also see Why does printf not flush after the call unless a newline is in the format string?
Try adding '\n' to your printf statements, like so:
#include <stdio.h>
int main() {
printf("start\n");
sleep(5);
printf("stop\n");
}
The compiler is not executing this out of order. Just the output is getting accumulated, and then displayed when the program exits. The '\n' will invoke the line discipline in the tty drivers to flush the output.
Read this Q&A, it explains it.

Running fork and printing hello [duplicate]

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().

Resources