Why does write () print before printf () in output redirection?

So, I know that printf() above the write() level and ends up using write() . printf() buffered, and write() makes system calls.

Example 1, if I had to run a program from printf() to write() , then it would print printf() to write() .

Example 2, if I were to run the same program and go to redirect the output to a file, the value of write() is output before printf() .

 #include <stdio.h> #include <unistd.h> int main() { printf("This is a printf test\n"); write(STDOUT_FILENO, "This is a write test\n", 21); return 0; } 

I donโ€™t understand what is going on here. In example 1, is there a program waiting for printf() to exit before running write() ? In example 2, does the program redirect the first finished output? And since write() is a lower level and does not need a buffer, for example, printf() , is it printed first?

+4
source share
3 answers

You answered your question.

printf buffered, and write is not.

For output to the terminal, the C stdio system has a function that clears the buffers whenever it sees a new line '\n' . See the documentation for setvbuf for more information on stdio buffering.

But when a file is issued to increase speed, the stdio system does not clear the buffer. Therefore, write output is first output.

Here are some of the strace results for working on my Linux system:

fstat (1, {st_mode = S_IFCHR | 0620, st_rdev = makedev (136, 1), ...}) = 0
mmap (NULL, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) = 0x7f7880b41000
write (1, "This is a test printf \ n", 22) = 22
write (1, "This is a write test \ n \ 0", 22) = 22

fstat is where the stdio system determines the type of descriptor 1 of the output file. I believe that he looks at st_mode and sees that this is a personal device. The disk file will be a block device. mmap is the memory allocation for the stdio buffer, which is 4K. Then the output is recorded.

+6
source

This is due to output buffering performed by the standard C library. In the first case, since you are writing on the terminal, libc buffering is line-oriented (flash is forced every time the carriage returns) to immediately display text on the screen, interactivity of performance privileges ( which should not be a problem, since terminals should not be an object for loads of text). Because of this, printf output is written immediately with some write call, which happens before the next one that you explicitly do.

In the second case, libc detects that you are writing a file, so it provides buffering to improve performance; because of this, usually the first printf will not be passed immediately, and your write will happen before libc actually flushes the buffer.

Again, this is what usually happens. I donโ€™t think that this behavior is set by any standard ( edit:) , it is set by C99, see @Jonathan comment) (and in the second example, even with buffering enabled, the library may decide to make a flash anyway, for example, if the buffer is full your printf ).

+2
source

The internal printf will use write when its buffer is full. It can also write before the buffer is full if it detects that it is writing interactive output, such as stdout, that has not been redirected.

0
source

Source: https://habr.com/ru/post/1398927/


All Articles