Я слышал, что FIFO - это именованные каналы. И у них точно такая же семантика. С другой стороны, я думаю, что доменный сокет Unix очень похож на pipe (хотя я никогда не использовал его). Поэтому мне интересно, все ли они ссылаются на одну и ту же реализацию в ядре Linux. Есть идеи?
30
Ответы:
Доменные сокеты UNIX и FIFO могут совместно использовать некоторую часть своей реализации, но концептуально они очень разные. FIFO функционирует на очень низком уровне. Один процесс записывает байты в канал, а другой читает из него. Сокет домена UNIX ведет себя так же, как и сокет TCP / IP.
Сокет является двунаправленным и может использоваться многими процессами одновременно. Процесс может принимать несколько соединений в одном сокете и одновременно обслуживать несколько клиентов. Ядро каждый раз выдает новый файловый дескриптор
connect(2)
илиaccept(2)
вызывается из сокета. Пакеты всегда будут идти к правильному процессу.На FIFO это было бы невозможно. Для двунаправленной связи вам нужны два FIFO и пара FIFO для каждого из ваших клиентов. Нет возможности писать или читать избирательно, потому что это гораздо более примитивный способ общения.
Анонимные каналы и FIFO очень похожи. Разница в том, что анонимные каналы не существуют в виде файлов в файловой системе, поэтому ни один процесс не может
open(2)
это сделать. Они используются процессами, которые разделяют их другим методом. Если процесс открывает FIFO и затем выполняет, например, afork(2)
, его дочерний элемент наследует свои файловые дескрипторы и, среди них, канал.Доменные сокеты UNIX, анонимные каналы и FIFO похожи в том, что они используют сегменты разделяемой памяти. Детали реализации могут варьироваться от одной системы к другой, но идея всегда одна и та же:
присоединить одну и ту же часть памяти к отображению памяти двух разных процессов, чтобы они совместно использовали данные( правка: это был бы один очевидный способ реализовать это, но это не то, как это на самом деле делается в Linux, который просто использует память ядра для буферов, см. ответ по @ tjb63 ниже).
Затем ядро обрабатывает системные вызовы и абстрагирует механизм.
источник
Здесь довольно хорошее обсуждение этого вопроса: http://www.slideshare.net/divyekapoor/linux-kernel-implementation-of-pipes-and-fifos
Насколько я вижу, как из слайдов презентации, так и из источника @ http://lxr.free-electrons.com/source/fs/pipe.c - fifo реализованы как обертка вокруг pipe, а сами pipe - реализовано через виртуальную файловую систему pipefs ..
@lgeorget - каналы, по-видимому, используют память ядра для буферов между считывателями и авторами - они не используют «разделяемую память» как таковую и копируют память между адресными пространствами пользователя и ядра (например,
pipe_read
вызовыpipe_iov_copy_to_user
, которые вызывают__copy_to_user_inatomic
(илиcopy_to_user
) .__copy_to_user_inatomic
вызовыcopy_user_generic
, отражаемый на несколько реализаций ASM.источник
«FIFO» и « именованный канал» - это одно и то же, хотя и довольно сильно отличается от того, как оболочка обрабатывает «канал» (|) между двумя командами в командной строке.
Именованный канал (FIFO) - это один «файл», совместно используемый двумя программами, где одна пишет в него, а другая читает из него ... Сокет, с другой стороны, представляет собой «соединение» между двумя «файлами», которое может использовать сеть и находиться на разных компьютерах - где одна программа читает / пишет в один "файл", а другая программа читает / пишет в другой ... Я не думаю, что они похожи ... С другой стороны, оба сокеты и именованные каналы - а также файлы, устройства, символические ссылки - все используют inode, и все они реализуют некоторые общие функции (такие как чтение и запись).
источник
Я так не думаю, Джастин. Если я не ошибаюсь, и вполне возможно, я думаю, FIFO используют файл на диске, а сокеты Unix Domain используют память ядра.
Кроме того, как дополнение к вышеприведенному посту, который упомянул, что доменные сокеты Unix являются двунаправленными, это имеет место только при использовании сокета SOCK_STREAM. SOCK_DGRAM Доменные сокеты Unix, на самом деле, являются однонаправленными и могут отправлять () только из кода, который вызвал connect (), к коду, который вызвал bind ().
Конечно, код, который вызвал connect (), должен также вызвать bind (), чтобы создать собственную конечную точку, но это не имеет никакого отношения к вашему вопросу.
источник
Мои 2 цента ... Сокеты FIFO и UNIX являются двунаправленными (похожими), но сокеты имеют топологию "звезда", тогда как FIFO - это просто очередь (и, следовательно, не могут заменить друг друга), да, их реализация может совместно использовать код внутри.
**
источник