Основы многопоточного и распределенного программирования

Производители и потребители: каналы ОС Unix


Процесс-производитель выполняет вычисления и выводит поток результатов. Процесс-потребитель вводит и анализирует поток значений. Многие программы в той или иной форме являются производителями и/или потребителями. Сочетание становится особенно интерес­ным, если производители и потребители объединены в конвейер — последовательность процес­сов, в которой каждый из них потребляет данные выхода предшественника и производит дан­ные для последующего процесса. Классическим примером являются конвейеры в операцион­ной системе Unix, рассматриваемые здесь. Другие примеры приводятся в последующих главах.

Обычно прикладной процесс в ОС Unix считывает данные из стандартного файла ввода stdin и записывает в стандартный файл вывода stdout. Обычно файл ввода — это клавиатура термина­ла, с которого вызвано приложение, а файл вывода — дисплей этого терминала. Но одной из наи­более мощных функций, предложенных в ОС Unix, была возможность привязки стандартных "устройств" ввода-вывода к различным типам файлов. В частности, файлы stdin и/или stdout могут быть связаны с файлом данных или с "файлом" особого типа, который называется каналом.

Канал — это буфер (очередь типа FIFO, работающая по принципу "First m — first out", т.е. "первым вошел, первым вышел") между процессом-производителем и процессом-потребителем. Он содержит связанную последовательность символов. Новые значения допи­сываются к ней, когда производитель выполняет запись в канал. Символы удаляются, когда процесс-потребитель считывает их из канала.

Прикладная программа в ОС Unix только читает данные из файла stdin, не заботясь о том, откуда в действительности они туда попали. Если файл stdin связан с клавиатурой, на вход по­ступают символы, набранные на клавиатуре. Если файл stdin связан с определенным файлом, вводится последовательность символов из этого файла. Если файл stdin связан с каналом, то вводится последовательность символов, записанных в этот канал.
Аналогично приложение вы­полняет запись в файл s tdout, не заботясь о том, куда в действительности поступают данные.

1.7. Клиенты и серверы: файловые системы                                                                                33

Каналы ОС Unix обычно определяются с помощью одного из командных языков, напри­мер csh (С shell — "оболочка С"). В частности, печатные страницы оригинала этой книги создавались с помощью команды на языке csh, похожей на следующую:

sed  -f  Script  $*   |   tbl   |eqn   |   groff Macros  -

Этот конвейер содержит четыре команды: 1) sed, потоковый текстовый редактор; 2) tbl, процессор таблиц; 3) eqn, процессор уравнений и 4) groff, программа, создающая данные в формате Postscript из исходных файлов в формате troff. Каждая пара команд разделена вертикальной чертой, обозначающей канал в С shell.

На рис. 1.5 показана структура этого конвейера. Каждая команда является процессом-. фильтром. Вход фильтра sed образован файлом редактирующих команд (Script) и аргумен­тами командной строки ($*), которыми в данном случае являются соответствующие исход­ные файлы текста книги. Выход редактора sed передается программе tbl, направляющей свои выходные данные программе egn, а та передает свой выход программе groff. Фильтр groff читает файл Macros для этой книги, считывает и обрабатывает свой стандартный вход, а затем отсылает выход на принтер в офисе автора.



Каждый поток на рис. 1.5 реализован связанным буфером: синхронизированной очередью значений типа FIFO. Процесс-производитель ожидает (при необходимости), пока в буфере появится свободное место, затем добавляет в конец буфера новую строку. Процесс-потребитель ожидает (при необходимости), пока в буфере не появится строка данных, затем забирает ее. В части 1 показано, как реализовать такие буферы с использованием разделяемых переменных и различных примитивов синхронизации (флагов, семафоров и мониторов). В части 2 представлены каналы взаимодействия и примитивы пересылки сообщений send (отослать) и receive (получить).Затем будет показано, как с их использованием програм­мируются фильтры, а с помощью буферов реализуются каналы и передача сообщений.


Содержание раздела