Pourquoi utiliser un canal nommé plutôt qu'un fichier?

42

J'ai récemment lu sur les pipes nommées et je ne comprenais pas pourquoi elles existaient.
J'ai lu quelque part que l'utilisation d'un canal nommé prend moins de temps que l'utilisation d'un fichier.

Pourquoi cela est-il ainsi?
Les canaux nommés doivent également être stockés en mémoire (et éventuellement échangés, comme des fichiers).
Autant que je sache, ils doivent obtenir un inode qui doit être référencé par le répertoire courant, tout comme les fichiers. En outre, ils doivent être supprimés par le programmeur, tout comme les fichiers.

Alors, où est l'avantage?

utilisateur3122885
la source
Cela ne fait pas partie d'un devoir de classe, n'est-ce pas?
don.joey
7
non ... en fait, je parcourais quelques notes de cours quand j'ai trouvé cette question et je ne pouvais pas y répondre ... et s'il s'agissait d'une tâche, je ne vois pas en quoi cela serait pertinent ... ce n'est pas comme Je ne chercherais pas la réponse avant de la trouver
user3122885

Réponses:

41

Presque tout dans Linux peut être considéré comme un fichier , mais la principale différence entre un fichier standard et un canal nommé est qu’un canal nommé est une instance spéciale d’un fichier qui ne contient aucun contenu sur le système de fichiers.

Voici la citation de man fifo:

Un fichier spécial FIFO (un canal nommé) est similaire à un canal, à la différence qu’il est accessible en tant que partie du système de fichiers. Il peut être ouvert par plusieurs processus de lecture ou d'écriture. Lorsque les processus échangent des données via la FIFO, le noyau transmet toutes les données en interne sans les écrire dans le système de fichiers. Ainsi, le fichier spécial FIFO n'a pas de contenu sur le système de fichiers; l'entrée de système de fichiers sert simplement de point de référence pour que les processus puissent accéder au canal de communication en utilisant un nom dans le système de fichiers.

Le noyau conserve exactement un objet de canal pour chaque fichier spécial FIFO ouvert par au moins un processus. La FIFO doit être ouverte aux deux extrémités (lecture et écriture) avant que les données puissent être transmises. Normalement, l’ouverture des blocs FIFO jusqu’à ce que l’autre extrémité soit également ouverte.

Donc, en réalité, un canal nommé ne fait rien jusqu’à ce qu’un processus l’ait lu et écrit. Il ne prend aucun espace sur le disque dur (sauf un peu de méta-information), il n'utilise pas le processeur.

Vous pouvez le vérifier en faisant ceci:

Créer un pipe nommée

$ mkfifo /tmp/testpipe

Allez dans un répertoire, par exemple /home/user/Documents, et gzip tout ce qui se trouve à l'intérieur, en utilisant le tube nommé.

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

Ici, vous devriez voir le PID du processus gzip. Dans notre exemple, il s’agissait de 28584.

Maintenant, vérifiez ce que fait ce 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

Vous verrez qu'il n'utilise aucune ressource . 0% d'utilisation du processeur, 0% d'utilisation de la mémoire.

Vérifier l'intuition concernant l'utilisation de l'espace fichier

$ du -h /tmp/testpipe
0   testpipe

Et encore 0rien. Le testpipe peut être réutilisé si nécessaire.

N'oubliez pas de tuer gzip avec kill -15 28584. Et retirez notre pipe nommée en utilisantrm /tmp/testpipe

Exemples d'utilisation

Vous pouvez rediriger presque tout en utilisant un tube nommé. Comme exemple, vous pouvez voir ce proxy d’une seule ligne .

De plus, voici une autre explication intéressante de l’utilisation des canaux nommés. Vous pouvez configurer deux processus sur un serveur pour qu'ils communiquent en utilisant un canal nommé au lieu d'une pile TCP / IP. Il est beaucoup plus rapide et ne charge pas les ressources du réseau. Par exemple, votre serveur Web peut communiquer avec la base de données directement à l'aide d'un canal nommé, au lieu d'utiliser une localhostadresse ou d'écouter un port.

c0rp
la source
15

Il est vrai que vous n'utiliserez pas de mémoire système, mais le fait que vous n'utilisiez pas cpu dans votre exemple est uniquement dû au fait que vous ne lisez pas le canal, le processus est en attente.

Considérons l'exemple suivant:

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

Maintenant ouvrez une nouvelle console et lancez:

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

Et dans une troisième console:

cat /tmp/testpipe > /dev/null

Si vous regardez la montre cmd (2ème trimestre), elle montrera une augmentation de la consommation de processeurs!

GARCIN David
la source
2
Cette réponse concerne la réponse de
c0rp
2

Voici un cas d'utilisation où les canaux nommés peuvent vous faire gagner beaucoup de temps en supprimant les E / S.

Supposons que vous ayez un BigFile, par exemple 10G.

Vous avez également des fractionnements de ce BigFile en morceaux de 1G, BigFileSplit_01 à BigFile_Split_10.

Maintenant, vous avez un doute sur l'exactitude de BigFileSplit_05

Naïvement, sans les tuyaux nommés, vous créez une nouvelle division à partir de BigFile et comparez:

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

Avec des pipes nommés vous feriez

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

Cela peut ne pas sembler à première vue une grande différence ... mais avec le temps, la différence est énorme!

Option 1:

  • dd: lire 1G / écrire 1G (1)
  • diff: lu 2G
  • rm: entrée de répertoire libre des clusters alloués / remove

Option 2:

  • dd: rien! (va au tuyau nommé)
  • diff: lu 2G
  • rm: pas de cluster alloué à gérer (nous n'avons rien écrit dans le système de fichiers) / entrée du répertoire remove

Donc, fondamentalement, le tube nommé vous enregistre ici une lecture et une écriture de la 1G ainsi que du nettoyage du système de fichiers (puisque nous n’avons rien écrit sur le système de fichiers à part le nœud fifo vide).

Ne pas faire d'E / S, en particulier d'écrire, est également utile pour éviter l'usure de vos disques. C'est encore plus intéressant lorsque vous travaillez avec des disques SSD, car ils ont un nombre limité d'écritures avant la mort des cellules.

(1) Évidemment, une autre option serait de créer ce fichier temporaire dans la RAM, par exemple si / tmp est monté sur la RAM (tmpfs). Néanmoins, vous seriez limité par la taille du disque RAM, alors que le "truc nommé" n'a pas de limite.

Zakhar
la source
1

Vous pouvez laisser un programme immobile et écouter un canal nommé pour un événement extérieur. Dès que l'événement extérieur se produit (par exemple, l'arrivée de nouvelles données), il peut être détecté par un autre programme qui ouvre le canal pour l'écriture et écrit les données d'événement correspondantes sur le canal. Lorsque la déclaration de fermeture est émise, le programme d'écoute reçoit le flux de données via le canal via une instruction de lecture et est prêt à traiter ce qu'il a. N'oubliez pas de fermer le tuyau après avoir lu le contenu. Le programme d'écoute peut également renvoyer les résultats de son traitement via le même outil ou via un autre canal nommé. De telles communications entre programmes sont parfois très pratiques.

Per Anton Ronning
la source