Что такое pipe в Linux
Что проверяют
Понимаете ли вы межпроцессное взаимодействие на уровне файловых дескрипторов. Для серверной разработки на Go это прикладной вопрос: запуск внешних процессов и связывание их потоков делается ровно этим механизмом.
Как отвечать
Pipe это однонаправленный буфер в ядре с парой дескрипторов, на чтение и на запись. Оболочка, встретив a | b, создаёт такую пару и подменяет дескрипторы: вывод первой команды становится концом записи, ввод второй концом чтения. Процессы запускаются одновременно и работают параллельно, данные текут потоком, промежуточный файл не нужен.
Дальше стоит описать поведение, ради которого вопрос и задают. Чтение из пустого буфера блокируется, пока открыт хотя бы один пишущий дескриптор, и возвращает признак конца данных, когда закрылся последний. Запись в буфер, у которого не осталось читателя, приводит к сигналу и к знакомому сообщению об оборванном канале. Размер буфера ограничен, при заполнении писатель ждёт, и это естественное сдерживание скорости.
Полезно различить анонимный канал, который наследуется только родственными процессами, и именованный FIFO: он создаётся в файловой системе и связывает любые процессы.
cmd := exec.Command("grep", "go")
cmd.Stdin = strings.NewReader(text)
out, err := cmd.Output()Где спотыкаются
Описывают канал как файл или как очередь с сохранением. Ничего не сохраняется: буфер небольшой, живёт в ядре, прочитанные байты исчезают, и второй читатель их уже не увидит.
Не закрывают свой конец на запись и получают вечное ожидание. Читатель не увидит конца данных, пока дескриптор открыт хоть у кого-то, включая родителя, который просто забыл его закрыть. В Go тот же сюжет с незакрытым потоком ввода процесса или с ожиданием завершения раньше вычитывания вывода.
Судят об успехе конвейера по коду возврата последнего звена. Упавшая середина остаётся незамеченной, пока не включён соответствующий режим оболочки. Сюда же вера в то, что при нескольких писателях строки не перемешаются, тогда как атомарна лишь запись до предела буфера.