Каналы являются однонаправленными средствами взаимодействия процессов, поэтому слабо подходят для двунаправленного обмена, например для организации обратной связи между процессами.
В большинстве случаев именованные каналы позволяют эффективно реализовать только простейшую модель взаимодействия «поставщик → потребитель», тогда, как для реализации модели «клиент сервер» используют специальное средство взаимодействия, называемое сокетом.
Сокет — устоявшаяся русская калька с англ, socket, буквально означающая «разъем», например, 220 В розетку и вилку, или сетевую розетку и вилку RJ-45, или 3,5 мм гнездо для наушников и соответствующий штекер.
Неименованные локальные (файловые) сокеты, как и неименованные каналы, являются «безымянными файлами», только двунаправленными, и так же предназначены для взаимодействия родственных процессов.
Для создания пары соединенных сокетов используется системный вызов socketpair, создающий пару файловых дескрипторов, каждый из которых используется одновременно и для приема (чтения), и для передачи (записи) информации.
Применение неименованных файловых сокетов проиллюстрировано в листинге ниже на примере синхрокопировщика rsync.
Копировщик оказывается параллельной программой, использующей сокеты для взаимодействия своих параллельных ветвей.
Неименованные локальные (файловые) сокеты Linux
fitz@ubuntu:~$ strace -fe socketpair,execve rsync -a /usr/share/doc /tmp/
execve(«/usr/bin/rsync», [«rsync», «-a», «/usr/sha’re/doc», «/tmp/»], [/* 42 vars */]) = 0
socketpair(PF_FILE, SOCK_STREAM, 0, [3, 4]) = 0
socketpair(PF_FILE, SOCK_STREAM, 0, [5, 6]) = 0
Process 5268 attached
[pid 5268] socketpair (PF_FILE, SOCK_STREAM, 0, [3, 4]) = 0
Process 5269 attached
^Z
[1]+ Остановлено strace -fe socketpair,execve rsync -a /usr/share/doc /tmp/
fitz@ubuntu:~$ ps f
PID TTY STAT TIME COMMAND
4838 pts/5 Ss 0:00 bash
5266 pts/5 T 0:00 \_ strace -fe socketpair execve rsync -a /usr/share/
5267 pts/5 t 0:00 | \_ rsync -a /usr/share/doc /tmp/
5268 pts/5 t 0:00 | \_ rsync -a /usr/share/doc /tmp/
5269 pts/5 t 0:00 | \_ rsync -a /usr/share/doc /tmp/
5301 pts/5 R+ 0:00 \_ ps f
fitz@ubuntu:~$ lsof -p 5269
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsync 5269 fitz cwd DIR ‘ 252,0 139264 26869761 /tmp
rsync 5269 fitz 0u Unix 0x00000000 0t0 1752340 socket
rsync 5269 fitz 4u Unix 0x00000000 0t0 1751443 socket
fitz@ubuntu:~$ lsof -p 5268
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsync 5268 fitz cwd DIR 252,0 139264 26869761 /tmp
rsync 5268 fitz 1u unix 0x00000000 0t0 1752343 socket
rsync 5268 fitz 3u unix 0x00000000 0t0 1751442 socket
fitz@ubuntu:~$ lsof -p 5267
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsync 5267 fitz cwd DIR 252,0 20480 3801093 /usr/share
rsync 5267 fitz 4u unix 0x00000000 0t0 1752341 socket
rsync 5267 fitz 5u unix 0x00000000 0t0 1752342 socket
Именованные и неименованные сокеты предоставляют эффективные средства для двунаправленного взаимодействия между процессами, в отличие от однонаправленных каналов, что делает их более гибкими и мощными инструментами для организации различных моделей взаимодействия. Использование системного вызова socketpair для создания пары соединенных сокетов позволяет реализовать эффективное взаимодействие между параллельными ветвями программы, что особенно полезно при создании параллельных приложений.