[Comm] Почему буферизация меняет порядок выводимых в файл строк?

Valentin Nechayev =?iso-8859-1?q?netch_=CE=C1_netch=2Ekiev=2Eua?=
Вс Окт 27 13:53:50 MSK 2002


 Fri, Oct 25, 2002 at 21:20:14, useperl wrote about "[Comm] Почему буферизация меняет порядок выводимых в файл строк?": 

> From: Henri Bourbon <useperl на fastmail.fm>
> Да,   в  свое  время меня очень обескуражил этот эффект. Теперь с этим я
> разобрался,  непонятно  же  другое:  почему  буферизация  может поменять
> *порядок* выводимых в файл строк. Поясняю:

Могут быть и более странные эффекты.
Дело в том, что если буфера не сброшены явно, то они сбрасываются при
выполнении exit(). А обычно libc построена так, что они сбрасываются
в порядке обратном стандартному порядку перечисления, то есть stderr
сбрасывается раньше, чем stdout.

У Вас слишком простой тест был. Вот более навороченный:

$ perl -we 'print "1-STDOUT\n"; warn "2-STDERR\n"; print "1-STDOUT\n"; warn "2-STDERR\n";'
1-STDOUT
2-STDERR
1-STDOUT
2-STDERR
$ perl -we 'print "1-STDOUT\n"; warn "2-STDERR\n"; print "1-STDOUT\n"; warn "2-STDERR\n";' 2>&1 | cat
2-STDERR
2-STDERR
1-STDOUT
1-STDOUT

Это подтверждает то, что я описал в дополнение к описанному ранее:
1. Из-за того, что не терминал, а пайп - буферизация идет поблочно, а не
построчно.
2. Блоки для stdout и stderr разные.
3. Буфер для stderr сбрасывается раньше.

А еще веселее получается, если stdout и stderr направлены в один пайп,
а вывода по каждому из них больше чем стандартный размер буфера (обычно 4K,
AFAIR). Когда буфер сбрасывается не по exit(), строки могут быть разрезаны
пополам.

На логи make это обычно не влияет потому, что от каждого процесса
выдача короткая. Но тоже бывает (если, например, много ошибок и много
нормального вывода).


/netch



Подробная информация о списке рассылки community