Introduction of Communication agenda
WHOAMI IPFactory 1 an @ n01e0 Je crée généralement des modules de noyau Linux.
WHAT IS IPC IPC est l'abréviation de * Inter Process Communication *. Cela signifie ** échange de données entre processus **, et divers types d'IPC sont disponibles sous Linux. Dans cet article, nous ne donnerons qu'une brève introduction à chacun, et n'expliquerons pas l'implémentation en détail. En effet, l'objectif est de comprendre les caractéristiques générales de chaque fonction et de faire le meilleur choix pour le lecteur.
L'IPC est grossièrement classé en trois types en fonction de sa fonction.
--La communication --Mécanisme de communication et d'échange de données entre processus --Synchronisation --Mécanisme de synchronisation entre processus et threads --Signal --Le signal est spécial et peut être utilisé pour la synchronisation et la communication en fonction des conditions.
IPC a été implémenté et mélangé selon plusieurs normes tout au long de la longue histoire d'UNIX. Il existe principalement des implémentations * System V * et des implémentations * POSIX * Dans l'ensemble, POSIX est plus facile à gérer, mais l'IPC de POSIX a été implémenté depuis la version 2.6 du noyau, il est donc moins portable.
Dans System V, la structure de données de chaque IPC se trouve dans l'espace noyau.
Généré dynamiquement lorsqu'un processus demande ** des ressources IPC (sémaphos, files d'attente de messages, régions de mémoire partagée) **.
Chaque ressource IPC a un identifiant unique. L'utilisateur peut distinguer chaque IPC avec une clé IPC différente.
Cette relation est similaire à la relation entre un fichier et un descripteur de fichier.
Cependant, la différence entre les fichiers est qu'ils restent en mémoire à moins que le processus ne les libère explicitement.
Il existe un ** POSIX IPC ** qui fournit des fonctionnalités similaires, qui est conçu pour être multi-thread sécurisé.
Une autre différence majeure est que POSIX permet à chaque IPC d'être nommé et distingué.
Il existe une règle de dénomination, il doit s'agir d'une chaîne terminée par un zéro qui commence par /
et a une longueur d'au moins un caractère autre que /
.
Bien qu'il existe de petites différences dans les spécifications, la principale différence dans le concept de chaque IPC est la méthode de gestion de chaque objet (ressource).
La principale différence entre System V et POSIX réside dans l'identificateur et le gestionnaire d'objet IPC, qui sont répertoriés.
Type IPC | identifiant | gestionnaire |
---|---|---|
tuyau | Aucun | Descripteur de fichier |
FIFO | chemin | Descripteur de fichier |
Système V semapho | Clé IPC System V | System V IPC ID |
POSIX Anonyme Semafo | Aucun | Pointeur Semapho |
POSIX nommé Semafo | Chemin IPC POSIX | Pointeur Semapho |
Message système V | Clé IPC System V | System V IPC ID |
Message POSIX | Chemin IPC POSIX | Descripteur de file d'attente de messages |
Mémoire partagée System V | Clé IPC System V | System V IPC ID |
Mémoire partagée POSIX | Chemin IPC POSIX | Descripteur de fichier |
Socket de domaine UNIX | chemin | Descripteur de fichier |
Prise de domaine Internet | Port d'adresse IP | Descripteur de fichier |
PIPE
C'est un concept très familier pour les lecteurs qui vivent dans la coquille au quotidien.
Pour décrire brièvement ce qu'est un tube (|
) dans un shell
** Connectez la sortie d'un processus à l'entrée d'un autre **
Cela signifie que.
De même, le tube ** IPC ** est souvent utilisé pour connecter la sortie et l'entrée de données.
J'ai essayé d'expliquer la structure de données des tuyaux en prenant quelque chose comme exemple, mais je ne peux penser à aucun bon exemple autre que les tuyaux.
Puisqu'il s'agit d'un cylindre, l'entrée et la sortie sont du premier entré, premier sorti.
En résumé, un tube est une ** structure de données unidirectionnelle premier entré, premier sorti **.
L'appel système pipe ()
défini dans ʻunistd.h produit deux descripteurs de fichier. L'un est pour la lecture et l'autre pour l'écriture. Ce sont des descripteurs de fichiers, mais il n'y a pas de chemin correspondant. Les données écrites dans le tube sont mises en mémoire tampon par la structure de données dans le noyau jusqu'à ce qu'elles soient lues. Normalement, lorsqu'un processus lit (
read ()`) un tube vide, il arrête la lecture jusqu'à ce que les données soient écrites dans ce tube.
FIFO Il existe une fonction similaire, «FIFO». Aussi appelé «tube nommé», comme son nom l'indique, il s'agit d'une structure de données ** first-in first-out **. La seule différence avec les tubes est que le descripteur de fichier créé a un ** nom ** (chemin).
SIGNAL C'est aussi un concept familier. On peut dire que le signal est aussi une sorte d'IPC. Il existe de nombreux types de signaux, prenons donc quelques exemples.
SIGHUP
SIGINT
SIGQUIT
SIGKILL
SIGSEGV
etc. Les signaux sont principalement utilisés pour indiquer à un processus que quelque chose s'est produit ou pour forcer un processus à faire quelque chose de spécifique. La quantité d'informations que possède un signal est faible et, généralement, il ne contient aucune information autre que le nombre (type). En outre, la manière de gérer le signal reçu dépend du processus.
Il existe plusieurs modèles pour répondre aux signaux
À quelques exceptions près, le signal reçu peut être ignoré. Quels sont les signaux qui ne peuvent être ignorés?
SIGKILL
SIGSTOP
Le processus qui reçoit ces signaux effectue toujours l'opération de réglage standard.
Comme son nom l'indique, l'opération de réglage standard est la réaction à chaque signal défini en standard sous Linux. Certains signaux sont définis sur ** end **, ** dump **, ** stop ** et ** ignore ** par défaut.
En plus de l'opération de réglage standard, l'utilisateur peut définir la correspondance pour chaque signal en utilisant signal ()
.
Lorsqu'un processus envoie un signal au processus, le signal est reçu par le noyau.
Le noyau vérifie si le processus cible est en cours d'exécution et met le signal en attente si ce n'est pas le cas.
L'appel système signal ()
a un pointeur vers la fonction qui devient le gestionnaire de signal correspondant au type de signal en tant qu'argument, et les associe.
SEMAPHORE Semafo est un mécanisme de ** synchronisation ** dans la classification IPC. La condition réelle de semapho est une valeur entière. Affecté en tant que compteur de contrôle d'accès pour protéger les ressources partagées par plusieurs processus
Consiste en.
Cela devient un compteur. Cette valeur indique l'état de la ressource (qu'elle soit disponible ou non)
Liste des processus en attente de disponibilité des ressources
Comptez le sémapho de haut en bas. Lorsqu'un processus accède à une ressource protégée par un sémapho, il décompte d'abord le sémafo associé à la ressource cible. Si le nombre de sémaphos devient négatif, le processus sera interrompu et ajouté à la liste. Lorsque l'accès à la ressource est terminé, le processus compte le sémapho. Cela redémarrera le processus de liste lorsque la valeur du sémapho deviendra positive.
Le sémapho lui-même ne limite pas le fonctionnement du processus, c'est l'utilisateur qui rend le sémafo significatif. De plus, comme le sémapho est un mécanisme de synchronisation, il nécessite une opération très compliquée.
System V
Créez ou ouvrez un sémapho avec semget ()
.
Utilisez le semapho avec semop ()
.
POSIX Dans POSIX, il existe deux types de semafo
Comme les autres IPC de POSIX, vous pouvez nommer et gérer vos sémaphos. Partager le sémaphos entre les processus en partageant les noms
Mappé sur la mémoire partagée. Partagez le sémapho en partageant la mémoire entre les processus et les threads sans nom.
MESSAGE La file d'attente de messages IPC est, comme son nom l'indique, une file d'attente. Les messages envoyés par un processus sont placés dans la file d'attente de messages jusqu'à ce qu'ils soient lus par un autre processus. Lorsqu'un autre processus lit le message, le noyau supprime le message de la file d'attente. Par conséquent, l'échange de messages entre processus se fait toujours de manière individuelle.
System V
Pour les données envoyées sous forme de message, la priorité du message doit toujours être spécifiée sous forme de valeur entière.
Le destinataire reçoit le message en spécifiant la priorité.
(Dans ce cas, il se peut qu'il ne s'agisse pas du premier entré, premier sorti, alors puis-je l'appeler * queue *?)
Récupérez la file d'attente en utilisant msgget ()
, envoyez-la avec messnd ()
, et recevez-la avec msgrcv ()
.
POSIX
La file d'attente de messages POSIX est également nommée et gérée.
Lors de la réception, il n'est pas possible de spécifier la priorité du message.
Le message le plus ancien avec la priorité la plus élevée est lu.
Ouvrez la file d'attente avec mq_open ()
, envoyez avec mq_send
et recevez avec mq_receive
.
SHARED MEMORY Mémoire partagée IPC Comme son nom l'indique, placez une structure de données spécifique dans l'espace mémoire partagé. En outre, alors que d'autres IPC transfèrent des données de l'espace utilisateur vers la structure de données dans l'espace noyau au moment de l'exécution, la surcharge est faible car elle ne correspond qu'à l'espace mémoire partagé. Cependant, il y a un problème à garder à l'esprit que le noyau n'est pas impliqué. ** Il est nécessaire d'empêcher plusieurs processus d'accéder en même temps **, et le sémapho mentionné ci-dessus peut être utilisé à cette fin.
System V
--Créez un segment de mémoire partagée ou obtenez l'ID d'un segment existant avec shmget ()
shmat ()
**shmdt ()
.Le segment de mémoire partagée attaché peut être traité de la même manière que la mémoire normale dans le programme.
L'objet de mémoire partagée est détruit lorsque tous les processus sont détachés et supprimés par shmctl ()
.
POSIX
--Ouvrez un objet de mémoire partagée avec shm_open ()
. La valeur de retour est un descripteur de fichier.
--Définissez le drapeau MAP_SHARED
sur le descripteur de fichier obtenu etmmap ()
SOCKET prise. Les sockets peuvent être classés en deux types selon la méthode de transfert de données.
Est appelé. Comme son nom l'indique, les sockets de flux peuvent être traités comme des flux, et comme des fichiers, n'importe quel nombre d'octets peut être lu quelle que soit la taille écrite. Les sockets de datagramme sont similaires aux messages, etc., avec des coupures spécifiques dans les données, et la lecture nécessite la lecture de toutes les données. En outre, comme autre classification des prises, il existe également une classification par destination de communication.
--Socket de domaine UNIX --Socket de domaine Internet
Appelé Les sockets de domaine UNIX prennent en charge la communication entre les applications au sein du même hôte, et les sockets de domaine Internet prennent en charge la communication entre les applications connectées par le protocole Internet.
Appels système liés au fonctionnement du socket
socket()
--Créer un nouveau socketbind()
--Connectez la prise à l'adresselisten()
accept()
--Obtenir une demande de connexion pour un socket prêt à accepterconnect()
--Établir la connexion avec d'autres prisesNous ne pouvons introduire ici qu'une petite partie des sockets, mais c'est un concept qui permet un grand nombre de choses. C'est la limite de l'article de synthèse IPC, mais il existe de nombreux articles sur les sockets, veuillez donc vous y référer si nécessaire.
Il est pratique d'identifier les caractéristiques, les forces et les faiblesses de chacun et d'utiliser l'IPC optimal. Dans mon cas, j'utilise la file d'attente de messages POSIX pour échanger des chemins de fichiers et ainsi de suite.
J'ai écrit beaucoup de conneries, mais j'aimerais rassembler un échantillon de chaque implémentation si nécessaire.
Recommended Posts