Общие сведения о конвейерных командах в Unix / Linux

Использование testdisk для восстановления файлов является находкой во многих ситуациях, с которыми я сталкивался. Для того, чтобы это работало бесперебойно, вы должны иметь возможность размонтировать жесткий диск, прежде чем вы сможете найти узел, который хотите восстановить. Этот пакет использует extundelete в качестве зависимости для выполнения работы, которая была золотой звездой в моем выздоровлении .... каждый раз.

16
22.04.2019, 20:15
2 ответа

Единственное, что в вашем вопросе выделяется как неправильное , это то, что вы говорите

A would run first, then B gets the stdout of A

На самом деле обе программы будут запускаться почти одновременно. Если нет ввода для B, когда он пытается прочитать, он будет блокироваться до тех пор, пока не будет ввода для чтения. Точно так же, если никто не читает вывод из A, его записи будут блокироваться до тех пор, пока его вывод не будет прочитан (, некоторые из них будут буферизированы каналом ).

Единственное, что синхронизирует процессы, участвующие в конвейере, — это ввод-вывод, то есть чтение и запись по конвейеру. Если записи или чтения не происходит, то эти два процесса будут выполняться полностью независимо друг от друга. Если один игнорирует чтение или запись другого, игнорируемый процесс блокируется и в конечном итоге уничтожается сигналом SIGPIPE(, если он записывает )или получает условие конца -из -файла на своем стандартном входной поток (, если читается ), когда другой процесс завершается.

Идиоматический способ описать A | Bсостоит в том, что это конвейер, содержащий две программы. Вывод, произведенный на стандартном выходе из первой программы, доступен для чтения на стандартном вводе второй ("[вывод] Aпередается в [вход] B" ). Оболочка выполняет необходимую сантехнику, чтобы это произошло.

Если вы хотите использовать слова «потребитель» и «производитель», думаю, это тоже нормально.

Тот факт, что это программы, написанные на C, значения не имеет.То, что это Linux, macOS, OpenBSD или AIX, значения не имеет.

27
27.01.2020, 19:48

В документации обычно используется термин «конвейер», который состоит из одной или нескольких команд, см. определение POSIX С технической точки зрения, у вас есть две команды, два подпроцесса для оболочки (либо fork()+exec()внешние команды, либо подоболочки)

Что касается части производителя -потребителя , конвейер может быть описан этим шаблоном, поскольку:

  • Производитель и Потребитель совместно используют буфер фиксированного -размера, и, по крайней мере, в Linux и MacOS X существует фиксированный размер буфера конвейера
  • Производитель и Потребитель слабо -связаны, команды в конвейере не знают о существовании друг друга (, если они активно не проверяют /proc/<pid>/fdкаталог ).
  • Производители пишут в stdout, а потребители читают stdin, как если бы они были одной выполняемой командой, иначе они могут существовать друг без друга .

Разница, которую я здесь вижу, заключается в том, что в отличие от Producer -Consumer на других языках, команды оболочки используют буферизацию и выводят стандартный вывод после заполнения буфера,но нет упоминания о том, что производитель -потребитель должен следовать этому правилу -только ждать, когда очередь заполнится, или отбрасывать данные (, чего конвейер не делает ).

2
27.01.2020, 19:48

Теги

Похожие вопросы