web-dev-qa-db-fra.com

Est-ce que la FIFO, la prise de domaine de tuyaux et unix la même chose dans le noyau Linux?

J'ai entendu dire que les FIFOS sont nommés tuyaux. Et ils ont exactement la même sémantique. D'autre part, je pense que le socket de domaine UNIX est assez similaire à la tuyau (bien que je ne l'ai jamais utilisé). Je me demande donc s'ils se réfèrent tous à la même implémentation dans le noyau Linux. Une idée?

32
Justin

Les prises de domaine UNIX et FIFO peuvent partager une partie de leur implémentation, mais elles sont conceptuellement très différentes. FIFO fonctionne à un niveau très bas. Un processus écrit des octets dans Le tuyau et l'autre en lit. Une prise de domaine UNIX a le même comportement qu'un socket TCP/IP.

Une prise est bidirectionnelle et peut être utilisée simultanément par de nombreux processus. Un processus peut accepter de nombreuses connexions sur la même socket et assister à plusieurs clients simultanément. Le noyau fournit un nouveau descripteur de fichier chaque fois que connect(2) ou accept(2) est appelé sur la prise. Les paquets vont toujours au bon processus.
[.____] sur une FIFO, ce serait impossible. Pour la communication bidirectionnelle, vous avez besoin de deux FIFOS 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 un moyen beaucoup plus primitif de communiquer.

Les tuyaux anonymes et les FIFOs sont très similaires. La différence est que les tuyaux anonymes n'existent pas comme des fichiers sur le système de fichiers, donc aucun processus ne peut open(2) It. Ils sont utilisés par des processus qui les partagent par une autre méthode. Si un processus ouvre un FIFOS, puis effectue, par exemple, une fork(2), son enfant héritera de ses descripteurs de fichiers et, entre eux, le tuyau.

Les prises de domaine UNIX, les tuyaux anonymes et les FIFOs sont similaires dans le fait qu'ils utilisent des segments de mémoire partagés. Les détails de la mise en œuvre peuvent varier d'un système à l'autre, mais l'idée est toujours la même: fixez la même partie de la mémoire dans deux processus distincts de mappage de mémoire pour les avoir partager des données
[.____] (éditer: Cela serait un moyen évident de la mettre en œuvre, mais ce n'est pas la manière dont il est réellement fait sous Linux, qui utilise simplement la mémoire du noyau pour les tampons, voir la réponse par @ TJB63 ci-dessous).
[.____] Le noyau gère ensuite les appels système et résoudra le mécanisme.

37
lgeorget

Il y en a une bonne bonne discussion ici: http://www.slideshare.net/divyekapoor /linux-kernel-implementation-of-pipes-and-fifos

Situé à ce que je puisse voir, à partir des diapositives de présentation et la source @ - http://lxr.free-electrons.com/source/fs/pipe.c - Les FIFO sont implémentés comme un wrapper Autour des tuyaux et des tuyaux eux-mêmes sont implémentés via le système de fichiers virtuel Pipsfs.

@Lgeorget - Les tuyaux semblent utiliser la mémoire du noyau pour les tampons entre les lecteurs et les écrivains - ils n'utilisent pas de "mémoire partagée" en tant que telle et copiez la mémoire entre les espaces d'adresses de l'utilisateur et du noyau (par exemple, pipe_read appels pipe_iov_copy_to_user, qui appelle __copy_to_user_inatomic (ou copy_to_user). __copy_to_user_inatomic appels copy_user_generic, qui est sur plusieurs implémentations de l'ASM.

7
tjb63

Un tuyau "FIFO" et A "nommé" est la même chose - bien qu'il soit très différent de la manière dont une coquille gère un "tuyau" (|) entre deux commandes sur la ligne de commande.

Un tuyau nommé (FIFO) est un seul "fichier" partagé par deux programmes, où on l'écrit et l'autre lue d'elle ... une prise de l'autre main est une "connexion" entre deux "fichiers" - qui peut Utilisez un réseau et soyez sur des ordinateurs séparés - où un programme lut/écrit à un "fichier" et un autre programme lu/écrit à l'autre ... Je ne pense pas qu'ils sont aussi semblables ... d'autre part les deux Des sockets et des tuyaux nommés - ainsi que des fichiers, des périphériques, des liens symboliques - tous utilisent des inodes, et ils implémentent tous des caractéristiques communes (comme lire et écrire).

4
Baard Kopperud

Mes 2 cents ... La prise FIFO et UNIX sont à la fois bidirectionnelle (similaire) mais la prise d'étoile a une topologie en étoile tandis que A FIFO est juste une file d'attente (et ne peut donc pas se remplacer), oui Leur mise en œuvre peut partager du code en interne.

Amateur

char * myfifo = "/tmp/myfifo";
mkfifo(myfifo, 0666);
fd = open(myfifo, O_RDWR);   //so that you can read/write to it
 ...
write(fd, buff1, sizeof(buff1));  
getchar();//wait till some one reds this and writes something else
int sz=read(fd, buff1, sizeof(buff1));  //read that something**
1
Asif Bahrainwala

Je ne pense pas si justin. Si je ne me trompe pas et que je suis bien possible, je pense que les FIFO utilisent un fichier sur disque et des prises de domaine UNIX utilisent la mémoire du noyau.

En outre, comme un ajout à l'affiche ci-dessus mentionnait que les prises de domaine UNIX sont bidirectionnelles, ce n'est que le cas lors de l'utilisation d'une prise Sock_stream. SOCK_DGRAM Unix Domain Les prises de domaine sont, en fait, unidirectionnelles et peuvent seulement envoyer () du code appelé Connect (), au code appelé BIND ().

Bien sûr, le code appelé Connect () doit également appeler la liaison () pour créer son propre point final, mais cela n'a rien à voir avec votre question.

1
Anonymous