Зачем использовать именованный канал вместо файла?

42

Я недавно читал о именованных каналах, и я не мог понять, почему они существуют.
Я где-то читал, что использование именованного канала занимает меньше времени, чем использование файла.

Почему это так?
Именованные каналы также должны храниться в памяти (и, возможно, заменяться, как файлы).
Насколько я вижу, они должны получить индекс, на который должна ссылаться текущая директория, как и файлы. Кроме того, они должны быть удалены программистом, как файлы.

Так в чем же преимущество?

user3122885
источник
Это не часть классного задания, не так ли?
don.joey
6
нет ... на самом деле я просматривал некоторые конспекты лекций, когда нашел этот вопрос, и я не смог ответить на него ... и если бы это было задание, я не понимаю, насколько это уместно ... это не так Я не буду искать ответ, пока не найду его
user3122885

Ответы:

41

Почти все в Linux можно считать файлом , но основное различие между обычным файлом и именованным каналом заключается в том, что именованный канал - это особый экземпляр файла, который не имеет содержимого в файловой системе.

Вот цитата из man fifo:

Специальный файл FIFO (именованный канал) похож на канал, за исключением того, что он доступен как часть файловой системы. Его можно открыть несколькими процессами для чтения или записи. Когда процессы обмениваются данными через FIFO, ядро ​​передает все данные внутренне, не записывая их в файловую систему. Таким образом, специальный файл FIFO не имеет содержимого в файловой системе; запись файловой системы просто служит контрольной точкой, так что процессы могут получить доступ к каналу, используя имя в файловой системе.

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

Так что на самом деле именованный канал ничего не делает, пока какой-то процесс не читает и не пишет в него. Он не занимает места на жестком диске (кроме небольшого количества мета-информации), он не использует процессор.

Вы можете проверить это, выполнив это:

Создать именованный канал

$ mkfifo /tmp/testpipe

Перейдите, например /home/user/Documents, к какому-либо каталогу и распакуйте все внутри него, используя именованный канал.

$ cd /home/user/Documents
$ tar cvf - . | gzip > /tmp/testpipe &
[1] 28584

Здесь вы должны увидеть PID процесса gzip. В нашем примере это было 28584.

Теперь проверьте, что делает этот PID

$ ps u -P 28584
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
c0rp     28584  0.0  0.0  29276  7800 pts/8    S    00:08   0:00 bash

Вы увидите, что он не использует ресурсы . 0% использования процессора, 0% использования памяти.

Проверьте догадку относительно использования файлового пространства

$ du -h /tmp/testpipe
0   testpipe

И опять 0ничего. Тестовая труба может быть использована снова, если это необходимо.

Не забудьте убить gzip, используя kill -15 28584. И удалите нашу именованную трубу, используяrm /tmp/testpipe

Примеры использования

Вы можете перенаправить почти все, используя именованный канал. В качестве примера вы можете увидеть этот прокси в одну строку .

Также вот еще одно приятное объяснение использования именованного канала. Вы можете настроить два процесса на одном сервере для связи с использованием именованного канала вместо стека TCP / IP. Это намного быстрее, и не загружает сетевые ресурсы. Например, ваш веб-сервер может взаимодействовать с базой данных напрямую, используя именованный канал, вместо использования localhostадреса или прослушивания какого-либо порта.

c0rp
источник
14

Это правда, что вы не будете использовать системную память, но тот факт, что вы не используете процессор в своем примере, объясняется только тем, что вы не читаете канал, поэтому процесс ожидает.

Рассмотрим следующий пример:

mkfifo /tmp/testpipe
tar cvf - / | gzip > /tmp/testpipe

Теперь откройте новую консоль и запустите:

watch -n 1 'ps u -P $(pidof tar)

И в третьей консоли:

cat /tmp/testpipe > /dev/null

Если вы посмотрите на часы cmd (2-й член), это покажет увеличение потребления процессора!

Гарцин Дэвид
источник
1
Этот ответ о ответе
c0rp
2

Вот пример использования, где именованные каналы могут сэкономить вам много времени, удалив ввод-вывод.

Предположим, у вас есть BigFile, например 10G.

У вас также есть разделение этого BigFile на части 1G, от BigFileSplit_01 до BigFile_Split_10.

Теперь у вас есть сомнения в правильности BigFileSplit_05

Наивно, без именованных каналов вы создадите новый сплит из BigFile и сравните:

dd if=BigFile of=BigFileSplitOrig_05 bs=1G skip=4 count=1
diff -s BigFileSplitOrig_05 BigFileSplit_05
rm BigFileSplitOrig_05

С именованными каналами вы бы сделали

mkfifo BigFileSplitOrig_05
dd if=BigFile of=BigFileSplitOrig_05 bs=1G skip=4 count=1 &
diff -s BigFileSplitOrig_05 BigFileSplit_05
rm BigFileSplitOrig_05

Это может показаться на первый взгляд не большой разницей ... но со временем разница огромна!

Опция 1:

  • дд: чтение 1G / запись 1G (1)
  • diff: читать 2G
  • rm: освободить выделенные кластеры / удалить запись каталога

Вариант 2:

  • дд: ничего! (идет к именованной трубе)
  • diff: читать 2G
  • rm: нет выделенного кластера для управления (на самом деле мы ничего не записывали в файловую систему) / удалить запись каталога

Таким образом, в основном именованный канал сохраняет здесь чтение и запись 1G плюс некоторую очистку файловой системы (поскольку мы ничего не записывали в файловую систему, кроме пустого узла fifo).

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

(1) Очевидно, что другим вариантом будет создание этого временного файла в ОЗУ, например, если / tmp смонтирован в ОЗУ (tmpfs). Тем не менее, вы будете ограничены размером RAM-диска, в то время как «трюк с именованным каналом» не имеет ограничений.

Захара
источник
1

Вы можете оставить программу неподвижной и прослушать именованный канал для какого-либо внешнего события. Как только происходит внешнее событие (например, поступление некоторых новых данных), это может быть обнаружено другой программой, которая, в свою очередь, открывает канал для записи, записывая соответствующие данные события в канал. Когда выдается оператор close, прослушивающая программа получает поток данных через канал через оператор read и готова обработать то, что получила. Не забудьте закрыть трубу после прочтения контента. Программа прослушивания также может возвращать результаты своей обработки через тот же или другой именованный канал. Такие межпрограммные коммуникации очень удобны.

Пер Антон Роннинг
источник