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

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

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

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

42
задан 21 May 2017 в 06:15

4 ответа

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

Вот кавычка от man fifo:

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

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

Таким образом, на самом деле именованный канал ничего не делает до некоторых чтений процесса и записей к нему. Это не занимает места на жестком диске (кроме определенной метаинформации), это не использует ЦП.

Можно проверить его путем выполнения этого:

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

$ mkfifo /tmp/testpipe

Перейдите к некоторому каталогу, например /home/user/Documents, и gzip все в нем, с помощью именованного канала.

$ 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, ничто. testpipe мог использоваться снова в случае необходимости.

Не забывайте уничтожать gzip, с помощью kill -15 28584. И удалите наше использование именованного канала rm /tmp/testpipe

Использования в качестве примера

Можно перенаправить почти все с помощью именованного канала. Как пример Вы видите этот прокси строки.

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

41
ответ дан 21 May 2017 в 06:15

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

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

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

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

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

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

cat /tmp/testpipe > /dev/null

при рассмотрении часов cmd (2-й срок) они покажут увеличение потребления ресурсов ЦП!

0
ответ дан 21 May 2017 в 06:15

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

0
ответ дан 21 May 2017 в 06:15

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

Позволяют нам предположить, что у Вас есть 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:

  • dd: читайте 1G / пишут 1G (1)
  • разность: считайте 2G
  • комната: бесплатные выделенные кластеры / удаляют Опцию 2 записи каталога

:

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

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

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

(1), Очевидно, другая опция состояла бы в том, чтобы создать тот временный файл к RAM, например, если/tmp смонтирован к RAM (tmpfs). Тем не менее, Вы были бы ограничены размером псевдодиска, тогда как "прием именованного канала" не имеет никаких пределов.

2
ответ дан 21 May 2017 в 06:15

Другие вопросы по тегам:

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