Le contenu de cet article est de présenter plusieurs types de fichiers sous Linux. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. [Recommandation du didacticiel vidéo : Tutoriel Linux]
Sous le système Linux, il existe sept types de fichiers :
Fichiers ordinaires ( - )
Répertoire (d)
Lien logiciel (lien de caractère L)
Fichier(S) Socket
Périphérique(s) de caractère
Bloquer le périphérique (B)
Fichier pipe (nommé pipe P)
Les fichiers, répertoires et liens logiciels normaux ne nécessitent aucune explication supplémentaire. Jetons un coup d'œil aux fichiers de canal, aux fichiers de socket, aux périphériques de caractères et aux types de périphériques de bloc.
Les tuyaux sont divisés en canaux anonymes et tuyaux nommés. Les tuyaux sont écrits à une extrémité et lus à l'autre extrémité. Il s'agit d'une transmission de données unidirectionnelle et leurs données sont transmises directement en mémoire. Les tuyaux sont un moyen de communication entre les processus, comme l'écriture du processus parent et la lecture du processus enfant. .
Dans le shell, le tube anonyme est un symbole de tube "|", tel que ls | grep xxx
, où le processus correspondant à ls est le processus parent dans ce groupe de processus indépendant, et le processus correspondant à grep est le processus enfant. Le processus parent écrit les lectures du processus enfant.
Dans les langages de programmation, les canaux anonymes sont implémentés en créant deux descripteurs de fichiers ou descripteurs de fichiers (tels que A, B). Un descripteur de fichier est utilisé pour écrire des données (telles que la fin d'écriture A, la fin d'écriture de données en entrant A). le poussera automatiquement dans B), et un autre descripteur de fichier est utilisé pour lire les données (c'est-à-dire B).
Pour les canaux nommés, c'est-à-dire les canaux avec des noms, les canaux nommés conservent les fichiers dans le système de fichiers, cela est également appelé FIFO, qui est premier entré, premier sorti. Bien que le fichier de canal nommé soit conservé dans le système de fichiers, ce fichier n'est qu'un point d'entrée pour l'utilisation du canal nommé. Lorsque vous utilisez le canal nommé pour transmettre des données, cela est toujours effectué dans la mémoire, ce qui signifie qu'il ne sera pas conservé. sur le système de fichiers. Les canaux nommés sont moins efficaces.
Dans le shell, vous pouvez utiliser la commande mknod
ou la commande mkfifo
pour créer un canal nommé. Les canaux nommés sont très utiles lors de l'écriture de scripts shell avec certains besoins particuliers. En fait, la fonction des coroutines (à l'aide de la commande coproc) est prise en charge depuis Bash 4 (ksh et zsh prennent depuis longtemps en charge les coroutines), mais les besoins des coroutines peuvent être satisfaits via des canaux nommés.
Les tuyaux généraux sont une communication unidirectionnelle et ne peuvent pas réaliser la fonction de communication bidirectionnelle, c'est-à-dire qu'ils ne peuvent qu'écrire et lire en même temps, mais ne peuvent pas lire et écrire des deux côtés. Si vous souhaitez établir une communication bidirectionnelle, vous pouvez créer deux canaux (il y a donc 4 descripteurs de fichiers, deux extrémités de lecture et deux extrémités d'écriture) ou utiliser un socket plus pratique.
Socket est utilisé pour réaliser la communication entre les deux extrémités. Comme analysé ci-dessus, il peut réaliser la fonction de communication inter-processus du pipeline bidirectionnel. De plus, les sockets peuvent également réaliser une communication inter-processus entre les hôtes via le réseau.
Les sockets doivent être appariées pour avoir un sens, c'est-à-dire qu'elles sont divisées en deux extrémités. Chaque extrémité a un descripteur de fichier (ou descripteur de fichier) pour la lecture et l'écriture, ce qui équivaut à deux communications bidirectionnelles. tuyaux.
Les sockets sont répartis en deux catégories selon la famille de protocoles : les sockets réseau (de type AF_INET, divisés en inet4 et inet6 selon ipv4 et ipv6) et les sockets de domaine Unix (de type AF_UNIX). Bien entendu, à partir de la famille de protocoles, les sockets peuvent être subdivisés en plusieurs types. Par exemple, les sockets INET peuvent être divisés en sockets TCP, sockets UDP, sockets de couche de liaison, sockets Raw, etc. Parmi eux, les sockets réseau constituent le fondement et le cœur de la programmation réseau.
Pour la communication inter-processus sur une seule machine, il est préférable d'utiliser le socket de domaine Unix plutôt que le socket Inet, car le socket de domaine Unix n'a pas de composant de communication réseau, et il suffit manque de beaucoup de fonctions réseau et est plus léger. En fait, les fonctions de pipeline implémentées par certains langages sur certaines plates-formes de systèmes d'exploitation sont implémentées via le domaine Unix, et on peut imaginer sa grande efficacité.
Le socket de domaine Unix a deux descripteurs de fichiers (tels que A, B). Les deux descripteurs de fichiers sont lisibles et inscriptibles en même temps. Lorsque le processus 1 écrit des données sur A, elles seront automatiquement transmises à B. Le processus 2 peut lire les données écrites de A à partir de B. De même, lorsque le processus 2 écrit des données sur B, elles seront automatiquement transmises à A. Le processus 1 peut lire les données écrites de B à partir de A. Comme suit :
进程1 进程2 ------------------------ A -----------> B B -----------> A
Dans les langages de programmation, la création d'un socket de domaine Unix a naturellement des fonctions correspondantes pour le créer facilement (peut être man socketpair
). Pour le shell bash, vous pouvez le créer via la commande nc
(NetCat), ou simplement utiliser deux canaux nommés pour implémenter les fonctions correspondantes. Si nécessaire, vous pouvez apprendre à utiliser les sockets de domaine Unix dans le shell bash.
Pour la communication inter-processus sur un réseau, des sockets réseau sont nécessaires. Chaque socket réseau est composée de 5 parties, appelées les 5 tuples du socket. Le format est le suivant :
{protocol, src_addr, src_port, dest_addr, dest_port}
c'est à dire protocole, adresse source, port source, adresse de destination, port de destination.
Chaque extrémité du socket a deux tampons dans l'espace du noyau (c'est-à-dire qu'une paire de sockets a 4 tampons), et chaque extrémité a un tampon de réception et un tampon d'envoi. Le processus 1 écrit des données dans le tampon d'envoi de son propre socket, qui seront envoyées au tampon recv du homologue, puis le processus 2 du homologue peut lire les données du tampon recv, et vice versa.
Mais avant de pouvoir réellement lire et écrire sur la prise réseau, la prise réseau a encore besoin de quelques paramètres. Une fois le socket serveur créé (fonction socket(), il y aura un descripteur de fichier ou un descripteur de fichier pour les opérations de lecture et d'écriture), il doit également lier l'adresse (via la fonction bind()) et le port d'écoute (via Listen ( )), le client n'a qu'à créer le socket et utiliser directement la fonction connect() pour lancer une demande de connexion au socket du serveur.
Pour les sockets TCP, lorsque le client initie une demande de connexion, cela signifie qu'il doit effectuer une négociation à trois avec le serveur (complété par le noyau et n'a rien à voir avec le processus de l'espace utilisateur). Décomposez chacune de ces trois poignées de main. La première fois que le client envoie une requête SYN, une fois que le serveur a reçu le SYN, le noyau place la connexion dans la file d'attente de synchronisation et définit le statut sur syn-recv, puis envoie ack+syn à Côté client, après avoir reçu l'accusé de réponse du client, le noyau déplace la connexion de la file d'attente de synchronisation vers la file d'attente établie (ou la file d'attente d'acceptation) et marque l'état de la connexion comme établi. Enfin, le processus en attente d'espace utilisateur lance l'appel système accept() pour permettre au noyau de le supprimer de la file d'attente d'acceptation. La connexion après avoir été acceptée() indique que la connexion a été établie, ce qui peut véritablement réaliser la transmission de données entre les processus aux deux extrémités.
Pour en savoir plus sur les principes des sockets TCP, consultez mon autre article : Le processus de connexion socket et TCP à connaître absolument.
Les périphériques blocs sont des périphériques matériels qui se distinguent par un accès aléatoire (pas nécessairement séquentiel) à des blocs de données de taille fixe. Un morceau de taille fixe est appelé un bloc. Le périphérique bloc le plus courant est le disque dur, mais de nombreux autres périphériques bloc existent également, tels que les lecteurs de disquettes, les lecteurs Blu-ray et la mémoire flash. Notez qu'il s'agit de périphériques sur lesquels des systèmes de fichiers sont montés, et que les systèmes de fichiers sont comme une lingua franca pour les périphériques bloc.
Les appareils de caractères sont accessibles via un flux continu de données, octet après octet. Les dispositifs de caractères typiques sont les terminaux (il existe de nombreux types de terminaux, à la fois physiques et virtuels) et le clavier .
Le moyen le plus simple de distinguer les périphériques bloc et les périphériques caractère est d'examiner la manière dont les données sont accessibles. Les périphériques de bloc sont accessibles de manière aléatoire pour obtenir des données, et les périphériques de caractères doivent être accessibles dans l'ordre des octets.
Si vous pouvez lire un peu de données ici, lire un peu de données là, et enfin les enchaîner en une donnée continue, alors il s'agit d'un périphérique bloc, tout comme les données sur le disque dur sont discontinues et il peut être nécessaire d'y accéder via une méthode d'accès aléatoire pour obtenir une donnée. Par exemple, dans un fichier légèrement plus volumineux sur un disque, les 10 000 premières données peuvent se trouver dans des blocs de données contigus ou dans des secteurs contigus, et les 10 000 données suivantes peuvent être éloignées ou même sur des cylindres différents.
Si chaque octet d'une donnée est dans le même ordre d'octets que lors de l'accès, c'est-à-dire que l'ordre des octets est complètement cohérent depuis le moment de l'accès jusqu'au traitement final des données, alors il s'agit d'un dispositif de caractère. En d’autres termes, les périphériques de caractères peuvent être considérés comme des périphériques de flux. Tout comme la saisie de données sur un clavier, si deux touches sont enfoncées en continu, les données en octets correspondant à ces deux touches doivent être saisies d'abord au recto puis au verso lors de leur réception. De la même manière, le terminal fonctionne de la même manière Lorsque le programme envoie des données au terminal, le programme affiche d'abord la lettre a, puis le chiffre 3. Ensuite, lorsqu'il est affiché sur le terminal, a doit être devant et 3 devant. le dos.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!