файловые описатели
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 31.03.18 15:56
Оценка:
Объясните, пожалуйста, как работает вот этот фрагмент:
https://github.com/Member1221/sharpmake/blob/master/code/smake.cs#L504-L543

Там есть цикл, в котором строки считываются из stdout и stderr поочерёдно.

Мне это кажется ошибкой, так как есть же в рантайме c привязка/синхронизация между выводом в stderr и stdout. Т.е. автор программы выводит сообщения в одном порядке, а этот фрагмент вывод будет перемешивать в другом порядке.

Всё правильно или я чего-то не понимаю?
Re: файловые описатели
От: Pavel Dvorkin Россия  
Дата: 31.03.18 16:05
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:

ЭФ>Мне это кажется ошибкой, так как есть же в рантайме c привязка/синхронизация между выводом в stderr и stdout. Т.е. автор программы выводит сообщения в одном порядке, а этот фрагмент вывод будет перемешивать в другом порядке.


stdout и stderr — это 2 разных файловых потока, со всем из этого вытекающим. Открыв оба, можно читать из каждого независимо. Аналогично тому, что можно читать независимо из двух потоков, открытых на разные файлы.
Кстати, под спудом тут файлы и лежат (точнее, пайпы)
With best regards
Pavel Dvorkin
Отредактировано 31.03.2018 16:06 Pavel Dvorkin . Предыдущая версия .
Re[2]: файловые описатели
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 31.03.18 20:35
Оценка:
PD> можно читать независимо из двух потоков, открытых на разные файлы.

Я ошибся, в C связываются между собой не stdout и stderr, а stdout и stdin:
http://qaru.site/questions/211294/why-do-we-need-to-tie-stdcin-and-stdcout
Re[2]: файловые описатели
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 31.03.18 20:49
Оценка:
PD> stdout и stderr — это 2 разных файловых потока

Зато когда создаётся виртуальный терминал, у него там всего два handle — один для ввода и один для вывода.
Это означает, что stdout и stderr оба помещаются в один поток в определённом порядке, а этот код этот порядок ломает.

Т.е. в настоящей консоли сообщения будут в одном порядке,
а при обработке этой программой — в другом. И от этого нежелательного эффекта хотелось бы избавится.
Отредактировано 31.03.2018 20:49 Эйнсток Файр . Предыдущая версия .
Re[3]: файловые описатели
От: Pavel Dvorkin Россия  
Дата: 01.04.18 02:48
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:

PD>> stdout и stderr — это 2 разных файловых потока


ЭФ>Зато когда создаётся виртуальный терминал, у него там всего два handle — один для ввода и один для вывода.

ЭФ>Это означает, что stdout и stderr оба помещаются в один поток в определённом порядке, а этот код этот порядок ломает.

ЭФ>Т.е. в настоящей консоли сообщения будут в одном порядке,

ЭФ>а при обработке этой программой — в другом. И от этого нежелательного эффекта хотелось бы избавится.

Если это так, значит, в терминале вызывается прямо или косвенно freopen

http://www.cplusplus.com/reference/cstdio/freopen/

This function is especially useful for redirecting predefined streams like stdin, stdout and stderr to specific files (see the example below).
With best regards
Pavel Dvorkin
Re[4]: файловые описатели
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 01.04.18 03:27
Оценка:
PD>Если это так, значит, в терминале вызывается прямо или косвенно freopen

Не очень понял, при чём тут freopen, и при чем тут программа "терминал", ведь обе они ошибку в коде в обсуждаемом фрагменте C# не исправят.

Итак, есть два сценария:
1) создаётся терминал, в нем запускается bash, он запускает прикладную программу, прикладная программа выводит в stdout и stderr
при этом stderr и stdout физически попадают в один "канал" в той последовательности, как их выводит прикладная программа
2) программа на C# запускает прикладную программу, прикладная программа выводит в stdout и stderr
при этом программа на C# чередует строчки из stderr и stdout так как ей нравится.

Тот факт, что где-то в терминале было что-то вызвано никак не влияет на то, что программа на C# написана криво.
Re[5]: файловые описатели
От: Pavel Dvorkin Россия  
Дата: 01.04.18 09:47
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:

ЭФ>1) создаётся терминал, в нем запускается bash, он запускает прикладную программу, прикладная программа выводит в stdout и stderr

ЭФ> при этом stderr и stdout физически попадают в один "канал" в той последовательности, как их выводит прикладная программа

Вполне возможно, что эта прикладная программа переназначила все на один поток.

ЭФ>2) программа на C# запускает прикладную программу, прикладная программа выводит в stdout и stderr

ЭФ> при этом программа на C# чередует строчки из stderr и stdout так как ей нравится.

ЭФ>Тот факт, что где-то в терминале было что-то вызвано никак не влияет на то, что программа на C# написана криво.


Она просто читает в предположении. что это разные потоки, вот и все. В общем случае это верно.
With best regards
Pavel Dvorkin
Re[6]: файловые описатели
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 01.04.18 13:07
Оценка:
PD> Она просто читает в предположении. что это разные потоки, вот и все. В общем случае это верно.

Это просто упрощающее предположение. Неправильное. Из-за его неправильности потом в реальном мире возникают проблемы у пользователей:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=9720
https://hisham.hm/2016/11/24/fun-hack-to-redirect-stdout-and-stderr-in-order/
https://unix.stackexchange.com/questions/295343/capture-all-output-error-warning-and-their-appearance-order-of-linuxs-command
https://stackoverflow.com/questions/17684764/bash-log-stdout-and-stderr-while-preserving-order-and-provenance
https://github.com/jupyter/help/issues/111
https://askubuntu.com/questions/382375/when-piping-output-to-a-file-why-are-stderr-and-stdout-in-the-wrong-order
https://superuser.com/questions/517256/obtain-both-merged-and-separated-stdout-and-stderr
Отредактировано 01.04.2018 13:15 Эйнсток Файр . Предыдущая версия . Еще …
Отредактировано 01.04.2018 13:11 Эйнсток Файр . Предыдущая версия .
Re[7]: файловые описатели
От: Pavel Dvorkin Россия  
Дата: 01.04.18 13:18
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:

PD>> Она просто читает в предположении. что это разные потоки, вот и все. В общем случае это верно.


ЭФ>Это просто упрощающее предположение. Неправильное. Из-за его неправильности потом в реальном мире возникают проблемы у пользователей:


Дело твое. Можешь считать это упрощающим и неправильным предположением, но тем не менее это так.

За Linux не поручусь, но вот для Windows

https://docs.microsoft.com/en-us/windows/console/getstdhandle

можно получить хендлы всех трех потоков, то есть файловые хендлы.

А уж когда в Windows дело дошло до родных ее HANDLE — тут начинают действовать известные правила, касающиеся этих хендлов (HANDLE есть неявный указатель на объект ядра, и для каждого HANDLE этот объект ядра свой).
With best regards
Pavel Dvorkin
Re[8]: файловые описатели
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 01.04.18 13:35
Оценка:
1. Проблема у пользователей есть
2. Проблему нужно решить (мне — для Linux, в Windows для решения проблем есть Microsoft)
3. Без доказательства говорить, что эта проблема проблема неразрешима — голословно.
4. Наличие трёх дескрипторов само-по-себе ничего не доказывает
Отредактировано 01.04.2018 13:38 Эйнсток Файр . Предыдущая версия . Еще …
Отредактировано 01.04.2018 13:37 Эйнсток Файр . Предыдущая версия .
Отредактировано 01.04.2018 13:36 Эйнсток Файр . Предыдущая версия .
Отредактировано 01.04.2018 13:36 Эйнсток Файр . Предыдущая версия .
Отредактировано 01.04.2018 13:36 Эйнсток Файр . Предыдущая версия .
Re[3]: файловые описатели
От: Sharov Россия  
Дата: 02.04.18 09:30
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:


ЭФ>Т.е. в настоящей консоли сообщения будут в одном порядке,

ЭФ>а при обработке этой программой — в другом. И от этого нежелательного эффекта хотелось бы избавится.

А могут оне быть взаимоисключающими, т.е. пишется либо в stderr, либо в stdout? Поэтому их и можно вычитать в одном цикле.
Кодом людям нужно помогать!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.