J'ai entendu dire que les FIFO s'appelaient des pipes. Et ils ont exactement la même sémantique. D'un autre côté, je pense que le socket de domaine Unix est assez similaire au pipe (bien que je ne m'en sois jamais servi). Je me demande donc s'ils font tous référence à la même implémentation dans le noyau Linux. Une idée?
30
Réponses:
Les sockets de domaine UNIX et FIFO peuvent partager une partie de leur implémentation mais ils sont conceptuellement très différents. FIFO fonctionne à un niveau très bas. Un processus écrit des octets dans le canal et un autre le lit. Un socket de domaine UNIX a le même comportement qu'un socket TCP / IP.
Un socket est bidirectionnel et peut être utilisé par de nombreux processus simultanément. Un processus peut accepter plusieurs connexions sur le même socket et assister simultanément plusieurs clients. Le noyau délivre un nouveau descripteur de fichier à chaque fois
connect(2)
ouaccept(2)
est appelé sur le socket. Les paquets iront toujours au bon processus.Sur un FIFO, ce serait impossible. Pour la communication bidirectionnelle, vous avez besoin de deux FIFO et vous avez besoin d'une paire de FIFO pour chacun de vos clients. Il n'y a aucun moyen d'écrire ou de lire de manière sélective, car ils sont une manière beaucoup plus primitive de communiquer.
Les canaux anonymes et les FIFO sont très similaires. La différence est que les canaux anonymes n'existent pas en tant que fichiers sur le système de fichiers, donc aucun processus ne peut le
open(2)
faire. Ils sont utilisés par des processus qui les partagent par une autre méthode. Si un processus ouvre un FIFO puis exécute, par exemple, unfork(2)
, son enfant héritera de ses descripteurs de fichier et, parmi eux, du canal.Les sockets de domaine UNIX, les canaux anonymes et les FIFO sont similaires dans la mesure où ils utilisent des segments de mémoire partagée. Les détails de l'implémentation peuvent varier d'un système à l'autre mais l'idée est toujours la même:
attachez la même portion de mémoire dans deux processus de mappage de mémoire distincts pour les faire partager des données( modifier: ce serait une façon évidente de l'implémenter mais c'est pas comment cela se fait réellement sous Linux, qui utilise simplement la mémoire du noyau pour les tampons, voir la réponse de @ tjb63 ci-dessous).
Le noyau gère ensuite les appels système et résume le mécanisme.
la source
Il y a une assez bonne discussion à ce sujet ici: http://www.slideshare.net/divyekapoor/linux-kernel-implementation-of-pipes-and-fifos
Pour autant que je puisse voir, à la fois à partir des diapositives de présentation et de la source @ http://lxr.free-electrons.com/source/fs/pipe.c - les fifo sont implémentés comme un wrapper autour des tuyaux, et les tuyaux eux-mêmes sont implémenté via le système de fichiers virtuel pipefs.
@lgeorget - Les canaux semblent utiliser la mémoire du noyau pour les tampons entre les lecteurs et les écrivains - ils n'utilisent pas la «mémoire partagée» en tant que telle, et copient la mémoire entre les espaces d'adressage utilisateur et noyau (par exemple, les
pipe_read
appelspipe_iov_copy_to_user
, qui appelle__copy_to_user_inatomic
(oucopy_to_user
) .__copy_to_user_inatomic
callscopy_user_generic
, qui fait partie de plusieurs implémentations ASM.la source
Un "FIFO" et un " pipe nommé " sont la même chose - bien que ce soit très différent de la façon dont un shell gère un "pipe" (|) entre deux commandes sur la ligne de commande.
Un canal nommé (FIFO) est un seul "fichier" partagé par deux programmes, où l'un y écrit et l'autre le lit ... Un socket d'autre part est une "connexion" entre deux "fichiers" - qui peut utiliser un réseau et être sur des ordinateurs séparés - où un programme lit / écrit dans un "fichier" et un autre programme lit / écrit dans l'autre ... Je ne pense pas qu'ils soient aussi similaires ... D'un autre côté, les deux les sockets et les canaux nommés - ainsi que les fichiers, les périphériques, les liens symboliques - utilisent tous des inodes et implémentent tous des fonctionnalités communes (comme la lecture et l'écriture).
la source
Je ne pense pas, Justin. Si je ne me trompe pas, et je le suis très probablement, je pense que les FIFO utilisent un fichier sur le disque, et les sockets de domaine Unix utilisent la mémoire du noyau.
En outre, en plus de l'affiche ci-dessus qui a mentionné que les sockets de domaine Unix sont bidirectionnelles, ce n'est le cas que lors de l'utilisation d'un socket SOCK_STREAM. SOCK_DGRAM Les sockets de domaine Unix sont en fait unidirectionnels et ne peuvent envoyer () qu'à partir du code qui a appelé connect (), vers le code qui a appelé bind ().
Bien sûr, le code qui a appelé connect () doit également appeler bind () pour créer son propre point de terminaison, mais cela n'a rien à voir avec votre question.
la source
Mes 2 cents ... FIFO et socket UNIX sont tous les deux bidirectionnels (similaires) mais le socket a une topologie en étoile tandis qu'un FIFO n'est qu'une file d'attente (et ne peut donc pas se remplacer), oui, leur implémentation peut partager du code en interne.
**
la source