Наши партнеры








Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

Анонимные каналы и именованные каналы

Пред. 

Глава 9. Файловая система Linux

 След.


«Анонимные» каналы и именованные каналы

Давайте вернемся назад к примеру с каналами, поскольку он весьма интересен, а также является хорошей иллюстрацией для понимания ссылок. Когда вы в командной строке используете канал, shell создает для вас канал и работает так, что команда перед каналом выполняет в него запись, а команда после канала выполняет из него чтение. Все каналы, будь они анонимными (как те, что используются в shell'ах) или именованными (смотрите ниже), все равно работают согласно принципу простой очереди FIFO («First In, First Out», т.е. "первым пришел - первым обслужен" ). Мы уже видели примеры использования каналов в shell'е, но давайте взглянем еще на один пример для демонстрации этого принципа:

$ ls -d /proc/[0-9] | head -5
/proc/1/
/proc/2/
/proc/3/
/proc/4/
/proc/5/

Одно обстоятельство, которое вы не заметите в этом примере (потому что это происходит слишком быстро), состоит в блокировке записей в каналы. Это означает, что когда команда ls выполняет запись в канал, он блокируется до тех пор, пока процесс выполняет чтение на другом конце. Чтобы увидеть этот эффект, вы можете создать именованные каналы, которые, в отличие от каналов, используемых shell'ами, имеют имена (т.е. они являются связанными, в то время как каналы shell'а - нет)[23]. Команда для создания именованного канала - mkfifo:

$ mkfifo a_pipe
$ ls -il
total 0
169 prw-rw-r--    1 queen     queen        0 Dec 10 14:12 a_pipe|
#
# Вы можете видеть, что счетчик ссылок равен 1,
# а файл является каналом ('p').
#
# Вы также можете использовать ln:
#
$ ln a_pipe the_same_pipe
$ ls -il
total 0
169 prw-rw-r--    2 queen     queen        0 Dec 10 15:37 a_pipe|
169 prw-rw-r--    2 queen     queen        0 Dec 10 15:37 the_same_pipe|
$ ls -d /proc/[0-9] >a_pipe
#
# Процесс заблокирован, т.к. на другом конце нет считывающей программы.
# Нажмите Control Z, чтобы приостановить процесс...
#
zsh: 3452 suspended  ls -d /proc/[0-9] > a_pipe
#
# ...а затем отправьте его в фоновый режим:
#
$ bg
[1]  + continued  ls -d /proc/[0-9] > a_pipe
#
# теперь выполнием чтение из канала...
#
$ head -5 <the_same_pipe
#
# ...процесс записи завершается....
#
[1]  + 3452 done       ls -d /proc/[0-9] > a_pipe
/proc/1/
/proc/2/
/proc/3/
/proc/4/
/proc/5/
#

Аналогичным образом чтение тоже блокируется. Если мы выполним приведенные выше команды в обратном порядке, мы увидим что команда head блокируется, ожидая, чтобы какой-либо процесс дал ей что-нибудь прочитать:

$ head -5 <a_pipe
#
# Программа заблокировалась, приостановите её: C+z
#
zsh: 741 suspended  head -5 < a_pipe
#
# Отправляем ее в фоновый режим...
#
$ bg
[1]  + continued  head -5 < a_pipe
#
# ...И скармливаем ей что-нибудь :)
#
$ ls -d /proc/[0-9] >the_same_pipe
$ /proc/1/
/proc/2/
/proc/3/
/proc/4/
/proc/5/
[1]  + 741 done       head -5 < a_pipe
$

Вы также можете увидеть нежелательный эффект в предыдущем примере: команда ls завершилась до того, как вступила в действие команда head. В результате вы немедленно возвратились в приглашение консоли, а head выполнилась позже, и вы увидели ее вывод только после возвращения.



[23] Существуют и другие различия между этими двумя типами каналов, но это выходит за рамки данной книги.


Пред. 

Уровень выше

 След.

Ссылки 

Начало

 Специальные файлы: Файлы символьного и блочного режима