Неименованные каналы Linux

Автор: | 04.12.2018

Кроме сигналов, которые могут использоваться как простейшие средства межпроцессного взаимодействия (IPC, inter-process communication), для эффективного обмена информацией между процессами используются каналы, сокеты, очереди сообщений и разделяемая память, а для синхронизации действий процессов над совместно используемыми объектами — семафоры.

Самым простым средством обмена информацией между родственными процессами (родитель и любые его потомки) являются неименованные каналы. Канал является «двусторонним однонаправленным безымянным файлом», с одного конца в который можно только записывать информацию, а с другого конца — только считывать.

В отличие от «обычного» файла, при открытии которого создается только один файловый дескриптор (и для чтения, и для записи файла), при создании канала создаются сразу два дескриптора — один для передачи (записи) в канал, а другой — для приема (чтения) из канала.

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

Использование неименованных каналов в системе широко распространено. Например, командный интерпретатор использует их для организации конвейерной обработки.

Архиватор tar использует, каналы аналогичным способом — для упаковки архивов «на лету» при помощи «внешних» упаковщиков.

В примере из листинга ниже посредством трассировщика strace отслеживается, системный вызов pipe, при помощи которого tar создает неименованный канал для связи с упаковщиком xz в дочернем процессе. Вся группа процессов архиватора tar приостановлена сигналом AZ SIGTSTP, после чего при помощи команды lsof показаны файловые дескрипторы открытых файлов обоих процессов.

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

fitz@ubuntu:~$ strace -fe ptpe,execve tar cJf /tnp/docs.tgz /usr/share/doc

plpe([3, 4]) =                                                      0

Process 3967 attached
tar: Удаляется начальный ‘/’ из имен объектов
[pid 3967] execve(«/usr/bin/xz», [«xz»), [/* 43 vars */]) = 0

^Z
[1]+ Остановлено strace -fe pipe tar cJf /tmp/docs.tgz /usr/share/doc

fitz@ubuntu:~$ ps f
PID   TTY            STAT      TIME   COMMAND

5472       pts/2          Ss           0:07      bash
3965      pts/2           T             0:00      \_ strace -fe pipe tar cJf   /tmp/docs.tgz /usr/share/doc
3966      pts/2           t             0:00      |      \_ tar cJf /tmp/docs.tgz /usr/share/doc
3967       pts/2          t              0:01      |             \- xz
3968      pts/2          R+          0:00      \_ ps f
fitz@ubuntu:~$ lsof -p 3966
COMMAND  PID   USER   FD   TYPE   DEVICE   SIZE/OFF         NODE   NAME
tar                 3966    fitz      cwd     DIR         252,0          69632   20316162   /home/fitz
tar                 3966    fitz       rtd      DIR         252,0            4096                  2    /
tar                 3966    fitz       txt      REG         252,0       305968    7208993   /bin/tar
tar                 3966    fitz        0u     CHR         136,2              0t0                   5    /dev/pts/2
tar                 3966    fitz        1u      CHR         136,2              0t0                   5     /dev/pts/2
tar                 3966    fitz        2u     CHR         136,2              0t0                   5     /dev/pts/2
tar                 3966    fitz         3r      DIR         252,0       106496     3801096   /usr/share/doc
tar                 3966    fitz       4w     FIFO             0,8              0t0      13S8926    pipe
fltz@ubuntu:~$ lsof -p 3967
COMMAND  PID   USER    FD    TYPE   DEVICE   SIZE/OFF       NODE   NAME

xz                   3967     fitz     cwd       DIR        252,0          69632  20316162 /home/fitz
xz                   3967     fitz      rtd       DIR         252,0            4096                 2   /
xz                   3967     fitz       txt      REG        252,0           67460  3802386  /usr/bin/xz
xz                   3967     fitz        0r     FIFO            0,8                0t0    1358926   pipe
xz                   3967     fitz       1w      REG        252,0       1466368 26874966 /tmp/docs.tgz
xz                   3967     fitz       2u      CHR         136,2               0t0                 5  /dev/pts/2

Нужно отметить, что в процессе архиватора PID=3966 файловый дескриптор передающей части канала сохранил свой номер, а в дочернем процессе упаковщика PID = 3967 файловый дескриптор принимающей части канала был перенаправлен на STDIN, как того и ожидает упаковщик xz.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *