Конвейер (Unix)

редактировать
Конвейер из трех программных процессов, выполняемых на текст te rminal

В Unix-подобных компьютерных операционных системах конвейер представляет собой механизм межпроцессного взаимодействия с использованием передачи сообщений. Конвейер - это набор процессов, объединенных в цепочку своими стандартными потоками, так что выходной текст каждого процесса (stdout ) передается непосредственно как вход (stdin ) к следующему. Второй процесс запускается, поскольку первый процесс все еще выполняется, и они выполняются одновременно. Идею конвейеров отстаивал Дуглас Макилрой на прародине Unix, в Bell Labs, во время разработки Unix, формируя его философию инструментария.. Он назван по аналогии с физическим конвейером . Ключевой особенностью этих конвейеров является «сокрытие внутренних компонентов» (Ritchie Thompson, 1974). Это, в свою очередь, обеспечивает большую ясность и простоту системы.

Эта статья посвящена анонимным каналам, где данные, записанные одним процессом, буферизуются операционной системой до тех пор, пока они не будут прочитаны следующим процессом, и этот однонаправленный канал исчезает, когда процессы завершены. Это отличается от именованных каналов, где сообщения передаются в канал или из канала, которому присвоено имя в виде файла, и остаются после завершения процессов. Стандартный синтаксис оболочки оболочки для анонимных каналов состоит в том, чтобы перечислить несколько команд, разделенных вертикальными чертами («каналы» в обычном слове Unix):

process1 | process2 | process3

Например, чтобы вывести список файлов в текущем каталоге (ls ), оставьте только строки вывода ls, содержащие строку "key" (grep ) и просмотрите результат на прокручиваемой странице (меньше ), пользователь вводит следующее в командной строке терминала:

ls -l | ключ grep | less

"ls -l"создает процесс, вывод (stdout) которого передается по конвейеру на ввод (stdin) процесса для" grep key ", а также для процесса для" less ". Каждый процесс принимает входные данные от предыдущего процесса и производит выходные данные для следующего процесса через стандартные потоки. Каждый «|» сообщает оболочке, что нужно подключить стандартный выход команда слева к стандартному вводу команды справа с помощью механизма межпроцессного взаимодействия, который называется (анонимный) канал, реализованный в операционной системе. Каналы являются однонаправленными; данные проходят по конвейеру слева направо.

Содержание

  • 1 Конвейеры в интерфейсах командной строки
    • 1.1 Поток ошибок
    • 1.2 Pipemill
  • 2 Создание конвейеров программным способом
  • 3 Реализация
    • 3.1 Сетевые каналы
  • 4 История
    • 4.1 Другие операционные системы
  • 5 См. Также
  • 6 Ссылки
  • 7 Внешние ссылки

Конвейеры в интерфейсах командной строки

Все широко используемые оболочки Unix ls имеет специальную синтаксическую конструкцию для создания конвейеров. При любом использовании команды записываются последовательно, разделенные символом ASCII вертикальной черты «|» (который по этой причине часто называют «трубкой персонаж"). Оболочка запускает процессы и устанавливает необходимые соединения между их стандартными потоками (включая некоторый объем памяти buffer ).

Поток ошибок

По умолчанию стандартные потоки ошибокstderr ») процессов в конвейере не передаются через труба; вместо этого они объединяются и направляются в консоль. Однако многие оболочки имеют дополнительный синтаксис для изменения этого поведения. Например, в оболочке csh использование «|» вместо «|» означает, что стандартный поток ошибок также должен быть объединен со стандартным выводом и переданы в следующий процесс. Bourne Shell также может объединять стандартную ошибку с |начиная с bash 4.0 или с помощью 2>1, а также перенаправлять ее в другой файл.

Pipemill

В наиболее часто используемых простых конвейерах оболочка соединяет серию подпроцессов через каналы и выполняет внешние команды внутри каждого подпроцесса. Таким образом, сама оболочка не выполняет прямой обработки данных, проходящих через конвейер.

Однако оболочка может выполнять обработку напрямую, используя так называемые mill или pipemill (поскольку команда прииспользуется для "измельчения" результатов начальной команды). Эта конструкция обычно выглядит примерно так:

команда | пока читаем -r var1 var2...; do # обрабатывать каждую строку, используя переменные, проанализированные в var1, var2 и т. д. # (обратите внимание, что это может быть подоболочка: var1, var2 и т. д. будут недоступны # после завершения цикла while; некоторые оболочки, такие как zsh и более новые # версии оболочки Korn обрабатывают команды слева от оператора pipe # в подоболочке) done

Такая конвейерная обработка может не работать должным образом, если тело цикла включает команды, такие как catи ssh, который читает из stdin : на первой итерации цикла такая программа (назовем ее стоком) будет читать оставшийся вывод из команда, и цикл завершится (с результатами в зависимости от специфики слива). Есть несколько способов избежать такого поведения. Во-первых, некоторые стоки поддерживают возможность отключения чтения из stdin(например, ssh -n). В качестве альтернативы, если стоку не нужно читать какой-либо ввод из stdin, чтобы сделать что-то полезное, ему можно передать < /dev/nullв качестве ввода.

Поскольку все компоненты конвейера выполняются параллельно, оболочка обычно формирует подпроцесс (подоболочку) для обработки своего содержимого, что делает невозможным распространение изменений переменных во внешнюю среду оболочки. Чтобы решить эту проблему, вместо этого «конвейер» может быть загружен из здесь документа, содержащего подстановку команды, которая ожидает завершения работы конвейера перед тем, как просмотреть содержимое. В качестве альтернативы для параллельного выполнения можно использовать именованный канал или процесс подстановки. GNU bash также имеет параметр lastpipeдля отключения разветвления для последнего компонента конвейера.

Создание конвейеров программным способом

Конвейеры могут быть созданы под управлением программы. Системный вызов Unix pipe() просит операционную систему создать новый объект анонимный канал. Это приводит к появлению двух новых открытых файловых дескрипторов в процессе: конец канала только для чтения и конец только для записи. Концы каналов выглядят как обычные анонимные файловые дескрипторы, за исключением того, что у них нет возможности поиска.

Чтобы избежать взаимоблокировки и использовать параллелизм, процесс Unix с одним или несколькими новыми каналами обычно вызывает fork() для создавать новые процессы. Затем каждый процесс закроет конец (и) канала, который он не будет использовать, прежде чем производить или потреблять какие-либо данные. В качестве альтернативы процесс может создавать новые потоки и использовать канал для связи между ними.

Именованные каналы также могут быть созданы с помощью mkfifo ()или mknod (), а затем представлены как входной или выходной файл для программ как они вызываются. Они позволяют создавать многопутевые каналы и особенно эффективны в сочетании со стандартным перенаправлением ошибок или с tee .

Реализация

В большинстве Unix-подобных систем все процессы конвейер запускается одновременно с их потоками, соответствующим образом подключенными, и управляется планировщиком вместе со всеми другими процессами, запущенными на машине. Важным аспектом этого, отличающим каналы Unix от других реализаций каналов, является концепция буферизации : например, программа-отправитель может производить 5000 байтов за секунду, и принимающая программа может принимать только 100 байтов в секунду, но данные не теряются. Вместо этого вывод программы-отправителя сохраняется в буфере. Когда принимающая программа готова к чтению данных, следующая программа в конвейере читает из буфера. В Linux размер буфера составляет 65 536 байт (64 КБ). Доступен сторонний фильтр с открытым исходным кодом под названием bfr для предоставления при необходимости буферов большего размера.

Сетевые каналы

Такие инструменты, как netcat и socat, могут подключать каналы к сокетам TCP / IP .

История

Концепция конвейера была изобретена Дугласом Макилроем и впервые описана на страницах руководства в Версия 3 Unix. Макилрой заметил, что большую часть времени командные оболочки передают выходной файл из одной программы в качестве входных данных в другую.

Его идеи были реализованы в 1973 году, когда («в одну лихорадочную ночь», - писал Макилрой) Кен Томпсон добавил системный вызов pipe ()и каналы в оболочку и несколько утилит в версии 3 Unix. «На следующий день, - продолжил Макилрой, - произошла незабываемая оргия шуток, когда все присоединились к азарту сантехники». Макилрой также приписывает Томпсону обозначение |, которое значительно упростило описание синтаксиса конвейера в версии 4.

Несмотря на то, что конвейеры Unix были разработаны независимо, они связаны с «связью» и предшествовали ей. files ', разработанный Кеном Лохнером в 1960-х годах для Дартмутской системы разделения времени.

. В Тони Хоаре последовательные процессы обмена (CSP) получили дальнейшее развитие трубки Макилроя.

Робот на значке Apple Automator, который также использует концепцию конвейера для связывания повторяющихся команд вместе, держит конвейер в знак уважения к исходной концепции Unix.

Другие операционные системы

Эта функция Unix была заимствована другими операционными системами, такими как Taos и MS-DOS, и в конечном итоге стало шаблоном проектирования конвейеров и фильтров разработки программного обеспечения.

См. также

Ссылки

Внешние ссылки

Последняя правка сделана 2021-06-02 06:37:53
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте