среда, 3 июня 2015 г.

FILE Stream Buffering

Существует три типа буферизации потоков вывода:
  • Без буферизации (_IONBF)
  • Построчная буферизация (_IOLBF)
  • Блочная буферизация (_IOFBF)
Манипулировать этими режимами можно при помощи функций 
setbuf, setbuffer, setlinebuf, setvbuf
Сколько строк напечатает данная программа?

Если скомпилировать и запустить, на экране появятся две строки:
$ gcc -Wall -pedantic example.c -o test
$ ./test
FIRST
SECOND
Однако, если перенаправить стандартный вывод в файл, то результат окажется несколько иным
$ ./test > file.txt
$ cat file.txt
FIRST
SECOND
SECOND
Все дело в буферизации. Когда текст выводится на терминал, буферизация по умолчанию работает в построчном режиме, однако, когда мы перенаправляем стандартный вывод в файл, буферизация уже находится в блочном режиме, и, следовательно, буфер не сбрасывается сразу после вызова библиотечной функции printf. А, так как этот буфер находится в user-space, его содержимое дублируется в дочернем процессе. Когда вызывается функция exit, буферы сбрасываются. Дублирование же данных переданных write не проиcходит из-за того, что write - системный вызов. Наглядно это можно увидеть, если в приведенном коде поменять местами две строки

Результат выполнения
$ gcc -Wall -pedantic example.c -o test
$ ./test
SECOND
FIRST
$ ./test > file.txt
$ cat file.txt
FIRST
SECOND
SECOND