Maison Tutoriel système Linux Explication détaillée du mécanisme RCU dans le noyau Linux

Explication détaillée du mécanisme RCU dans le noyau Linux

Feb 10, 2024 pm 09:09 PM
linux linux教程 linux系统 并发访问 linux命令 shell脚本 Mécanisme de synchronisation Linux embarqué Débuter avec Linux apprentissage Linux

Le noyau Linux est un système complexe qui doit gérer divers problèmes de concurrence, tels que la planification des processus, la gestion de la mémoire, les pilotes de périphériques, les protocoles réseau, etc. Afin de garantir la cohérence et l'exactitude des données, le noyau Linux fournit une variété de mécanismes de synchronisation, tels que des verrous tournants, des sémaphores, des verrous en lecture-écriture, etc. Cependant, ces mécanismes de synchronisation présentent quelques défauts, tels que :

Explication détaillée du mécanisme RCU dans le noyau Linux

  • Les verrous de rotation feront perdre du temps au processeur en attente et ne peuvent pas être utilisés dans les noyaux préemptifs
  •  ;
  • Le sémaphore entraînera la mise en veille et le réveil du processus, augmentant ainsi la surcharge de changement de contexte
  •  ;
  • Les verrous en lecture-écriture entraîneront une famine des écrivains ou des lecteurs, et lorsqu'il y a plus de lecteurs que d'écrivains, l'écrivain devra également payer les frais généraux liés à l'acquisition du verrou.

Alors, existe-t-il un meilleur mécanisme de synchronisation ? La réponse est oui, c'est RCU (Read Copy Update). RCU est un mécanisme de synchronisation basé sur le modèle de publication-abonnement, qui peut réaliser des opérations de lecture efficaces et des opérations de mise à jour à faible latence. L'idée de base de RCU est la suivante :

  • L'opération de lecture n'a pas besoin d'acquérir de verrous, utilisez simplement rcu_read_lock() et rcu_read_unlock() pour marquer la zone critique
  •  ;
  • L'opération de mise à jour nécessite d'abord de créer une copie des données, d'apporter des modifications sur la copie, puis d'utiliser rcu_assign_pointer() pour publier les nouvelles données, et d'utiliser call_rcu() ou synchroniser_rcu() pour attendre que toutes les opérations de lecture soient terminées avant de recycler les données. anciennes données.

Quels sont les avantages du RCU ? Il présente les fonctionnalités suivantes :

  • RCU peut réduire la concurrence de verrouillage et le changement de contexte, et améliorer les performances de concurrence et la réactivité du système
  •  ;
  • RCU peut éviter des problèmes tels que les blocages et l'inversion des priorités, simplifiant ainsi le modèle de programmation
  •  ;
  • RCU peut s'adapter à différents scénarios, tels que les systèmes temps réel, les systèmes NUMA, les systèmes SMP, etc. ; RCU peut être utilisé conjointement avec d'autres mécanismes de synchronisation, tels que les verrous de rotation, les opérations atomiques, etc.
  • Alors, comment fonctionne le RCU ? De quels scénarios d'application dispose-t-il ? Cet article présentera le mécanisme de synchronisation efficace de RCU sous deux aspects : le principe et l'application. L'idée de conception de RCU est relativement claire et la protection du partage sans verrouillage est obtenue en remplaçant les anciens et les nouveaux pointeurs. Mais en ce qui concerne le niveau du code, cela reste un peu difficile à comprendre. Dans le chapitre 4 de "Mécanisme approfondi du noyau du pilote de périphérique Linux", les règles suivies derrière RCU ont été très clairement décrites. Ces règles sont vues d'un point de vue relativement élevé, car je pense que trop d'analyse de code est facile. Laissez le lecteur se perdre. dans les détails. Après avoir reçu le livre récemment, j'ai relu attentivement le texte de la partie RCU et j'ai pensé que je devrais ajouter un peu plus de contenu, car certaines choses peuvent ne pas convenir à être écrites dans le livre.

Le signe que le côté lecture RCU entre dans la section critique est d'appeler rcu_read_lock. Le code de cette fonction est :

.
1. 
2. static inline void rcu_read_lock(void)
3. {
4. ​    __rcu_read_lock();
5. ​    __acquire(RCU);
6. ​    rcu_read_acquire();
7. }
Copier après la connexion

Il semble y avoir trois appels de fonction dans cette implémentation, mais le travail réel est effectué par la première fonction __rcu_read_lock(). __rcu_read_lock() désactive la préemption du noyau en appelant preempt_disable(). Mais les interruptions sont autorisées. Supposons que le lecteur se trouve dans la section critique rcu et qu'il vient de lire un pointeur p dans la zone de données partagées (mais n'a pas encore accédé aux données membres de p). Une interruption se produit et l'exemple de gestion des interruptions est activé. Il se trouve que l'ISR doit modifier la zone de données pointée par p. Selon les principes de conception de RCU, l'ISR allouera une nouvelle zone de données new_p de la même taille, puis copiera les données de l'ancienne zone de données p dans la nouvelle. zone de données, puis dans new_p Effectuez essentiellement le travail de modification des données (car elles sont modifiées dans l'espace new_p, il n'y a pas d'accès simultané à p, donc RCU est un mécanisme sans verrouillage, et c'est la raison), après l'ISR termine le travail de mise à jour des données, attribue new_p à p (p=new_p), et enfin il enregistrera une fonction de rappel pour libérer l'ancien pointeur p au moment approprié. Par conséquent, tant que toutes les références à l’ancien pointeur p sont terminées, il n’y a aucun problème à libérer p. Lorsque la routine de traitement des interruptions revient après avoir terminé ces tâches, le processus interrompu accédera toujours aux données dans l'espace p, c'est-à-dire aux anciennes données. Ce résultat est autorisé par le mécanisme RCU.

Les règles RCU autorisent des incohérences temporaires dans l'affichage des ressources causées par le basculement du pointeur entre les lecteurs et les rédacteurs

.

La prochaine question intéressante à propos de RCU est : quand l'ancien pointeur peut-il être libéré. La réponse à cette question que j'ai vue dans de nombreux livres est la suivante : lorsqu'un changement de processus se produit sur tous les processeurs du système. Cette réponse stylisée déroute souvent les lecteurs qui découvrent le mécanisme RCU. Pourquoi devons-nous attendre qu'un changement de processus se produise sur tous les processeurs avant d'appeler la fonction de rappel pour libérer l'ancien pointeur ? Ceci est en fait déterminé par les règles de conception de RCU : Toutes les références aux anciens pointeurs ne peuvent apparaître que dans la section critique incluse dans rcu_read_lock et rcu_read_unlock, et la commutation de processus n'est pas possible dans cette section critique , Une fois la section critique ne devrait plus n'ont plus aucune forme de référence à l'ancien pointeur p. Évidemment, cette règle exige que le lecteur ne puisse pas changer de processus dans la section critique, car une fois qu'il y a un changement de processus, la fonction de rappel qui libère l'ancien pointeur peut être appelée, provoquant la libération de l'ancien pointeur lors du changement de processus. est replanifié, il peut faire référence à un espace mémoire libéré.

Nous voyons maintenant pourquoi rcu_read_lock doit uniquement désactiver la préemption du noyau, car cela rend impossible la commutation et la suppression du processus actuel même si une interruption se produit dans la section critique. Les développeurs de noyau, ou plutôt les concepteurs de RCU, ne peuvent pas faire grand-chose. L'étape suivante relève de la responsabilité de l'utilisateur. Si une fonction est appelée dans la section critique de RCU, la fonction peut se mettre en veille, alors les règles de conception de RCU seront violées et le système entrera dans un état instable.

Cela montre une fois de plus que si vous voulez utiliser quelque chose, vous devez comprendre son mécanisme interne. Comme dans l'exemple mentionné ci-dessus, même s'il n'y a actuellement aucun problème avec le programme, les dangers cachés laissés dans le système sont comme une bombe à retardement. , ce qui peut arriver à tout moment. Une détonation, surtout s'il faut beaucoup de temps avant que le problème n'éclate soudainement. Dans la plupart des cas, le temps nécessaire pour trouver le problème peut être beaucoup plus long que pour se calmer et comprendre soigneusement les principes de la RCU.

Les lecteurs de RCU ont un degré de liberté plus élevé que les lecteurs de rwlock. Étant donné que le lecteur RCU n'a pas besoin de prendre en compte les sentiments de l'écrivain lorsqu'il accède à une ressource partagée, cela est différent du lecteur rwlock. Le lecteur rwlock doit s'assurer qu'aucun écrivain n'exploite la ressource lors de la lecture de la ressource partagée. La différence entre les deux vient du fait que RCU sépare les ressources partagées entre lecteurs et écrivains, tandis que les lecteurs et écrivains rwlock n'utilisent qu'une seule copie des ressources partagées du début à la fin. Cela signifie également que les rédacteurs de RCU doivent assumer davantage de responsabilités et qu'une sorte de mécanisme d'exclusion mutuelle doit être introduit entre plusieurs rédacteurs qui mettent à jour la même ressource partagée. RCU est donc un « mécanisme sans verrouillage ». La déclaration est limitée aux lecteurs et écrivains. Nous voyons donc que le mécanisme RCU doit être utilisé dans des situations où il y a un grand nombre d'opérations de lecture et relativement peu d'opérations de mise à jour. À l'heure actuelle, RCU peut grandement améliorer les performances du système, car l'opération de lecture de RCU n'entraîne pratiquement aucune surcharge de verrouillage par rapport à certains autres mécanismes de verrouillage.

En utilisation réelle, les ressources partagées existent souvent sous la forme de listes chaînées.Le noyau implémente plusieurs fonctions d'interface pour les opérations de liste chaînée en mode RCU, telles que list_add_tail_rcu, list_add_rcu, hlist_replace_rcu, etc. pour une utilisation spécifique, veuillez vous référer à certaines informations sur la programmation du noyau ou sur le pilote de périphérique.

En ce qui concerne la publication d'anciens pointeurs, le noyau Linux propose deux méthodes aux utilisateurs, l'une consiste à appeler call_rcu et l'autre à appeler synchroniser_rcu. La première est une méthode asynchrone. call_rcu placera la fonction de rappel qui libère l'ancien pointeur dans un nœud, puis ajoutera le nœud à la liste chaînée locale du processeur exécutant actuellement call_rcu dans la partie softirq de l'interruption d'horloge (RCU_SOFTIRQ ). , la fonction de traitement des interruptions logicielles rcu rcu_process_callbacks vérifiera si le processeur actuel a connu une période de veille (quiescente, qui implique la planification des processus du noyau et d'autres aspects. L'implémentation du code noyau de rcu détermine que tous les processeurs du système ont connu une période de veille). période (ce qui signifie qu'un changement de processus s'est produit sur tous les processeurs, donc l'ancien pointeur peut être libéré en toute sécurité à ce moment), la fonction de rappel fournie par call_rcu sera appelée.

L'implémentation de synchroniser_rcu utilise la file d'attente. Lors de son implémentation, elle ajoute également un nœud à la liste chaînée locale du processeur actuel comme call_rcu. La différence avec call_rcu est que la fonction de rappel dans ce nœud est wakeme_after_rcu, puis synchronise_rcu. dormira dans une file d'attente jusqu'à ce qu'un changement de processus se produise sur tous les processeurs du système, donc wakeme_after_rcu est appelé par rcu_process_callbacks pour réveiller le synchronisme_rcu endormi. Après avoir été réveillé, synchroniser_rcu sait qu'il peut maintenant libérer l'ancien pointeur.

Nous voyons donc que la fonction de rappel enregistrée n'a peut-être pas été appelée après le retour de call_rcu, ce qui signifie que l'ancien pointeur n'a pas été libéré, et l'ancien pointeur doit avoir été libéré après le retour de synchroniser_rcu. Par conséquent, l'appel de call_rcu ou de synchroniser_rcu dépend des besoins spécifiques et du contexte actuel. Par exemple, la fonction synchroniser_rcu ne peut pas être utilisée dans le contexte du traitement des interruptions.

Cet article présente RCU, un mécanisme de synchronisation efficace dans le noyau Linux. Il s'agit d'un mécanisme de synchronisation basé sur le modèle de publication-abonnement. Nous avons analysé les idées de base, les interfaces clés et les détails de mise en œuvre de RCU sous l'aspect principal, et avons donné des exemples de code correspondants. Nous avons également introduit l'utilisation de RCU dans les opérations de liste chaînée, la gestion des minuteries, le traitement des interruptions logicielles et d'autres scénarios du point de vue de l'application, et avons donné des exemples de code correspondants. En étudiant cet article, nous pouvons maîtriser l'utilisation de base de RCU et être en mesure d'utiliser RCU de manière flexible dans le développement réel pour répondre aux exigences de synchronisation efficaces. J'espère que cet article vous aidera !

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!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Quelle configuration de l'ordinateur est requise pour VScode Quelle configuration de l'ordinateur est requise pour VScode Apr 15, 2025 pm 09:48 PM

Vs Code Système Exigences: Système d'exploitation: Windows 10 et supérieur, MacOS 10.12 et supérieur, processeur de distribution Linux: minimum 1,6 GHz, recommandé 2,0 GHz et au-dessus de la mémoire: minimum 512 Mo, recommandée 4 Go et plus d'espace de stockage: Minimum 250 Mo, recommandée 1 Go et plus d'autres exigences: connexion du réseau stable, xorg / wayland (Linux) recommandé et recommandée et plus

VScode ne peut pas installer l'extension VScode ne peut pas installer l'extension Apr 15, 2025 pm 07:18 PM

Les raisons de l'installation des extensions de code vs peuvent être: l'instabilité du réseau, les autorisations insuffisantes, les problèmes de compatibilité système, la version de code vs est trop ancienne, un logiciel antivirus ou des interférences de pare-feu. En vérifiant les connexions réseau, les autorisations, les fichiers journaux, la mise à jour vs du code, la désactivation des logiciels de sécurité et le redémarrage du code ou des ordinateurs, vous pouvez progressivement dépanner et résoudre les problèmes.

Peut-on utiliser pour mac Peut-on utiliser pour mac Apr 15, 2025 pm 07:36 PM

VS Code est disponible sur Mac. Il a des extensions puissantes, l'intégration GIT, le terminal et le débogueur, et offre également une multitude d'options de configuration. Cependant, pour des projets particulièrement importants ou un développement hautement professionnel, le code vs peut avoir des performances ou des limitations fonctionnelles.

Qu'est-ce que VScode pour quoi est VScode? Qu'est-ce que VScode pour quoi est VScode? Apr 15, 2025 pm 06:45 PM

VS Code est le code Visual Studio Nom complet, qui est un éditeur de code multiplateforme gratuit et open source et un environnement de développement développé par Microsoft. Il prend en charge un large éventail de langages de programmation et fournit une mise en surbrillance de syntaxe, une complétion automatique du code, des extraits de code et des invites intelligentes pour améliorer l'efficacité de développement. Grâce à un écosystème d'extension riche, les utilisateurs peuvent ajouter des extensions à des besoins et des langues spécifiques, tels que les débogueurs, les outils de mise en forme de code et les intégrations GIT. VS Code comprend également un débogueur intuitif qui aide à trouver et à résoudre rapidement les bogues dans votre code.

Comment utiliser vscode Comment utiliser vscode Apr 15, 2025 pm 11:21 PM

Visual Studio Code (VSCODE) est un éditeur de code Open Source, Open Source et gratuit développé par Microsoft. Il est connu pour son léger, l'évolutivité et le support pour une large gamme de langages de programmation. Pour installer VScode, veuillez visiter le site officiel pour télécharger et exécuter l'installateur. Lorsque vous utilisez VSCODE, vous pouvez créer de nouveaux projets, modifier le code, déboguer le code, naviguer dans les projets, développer VSCODE et gérer les paramètres. VScode est disponible pour Windows, MacOS et Linux, prend en charge plusieurs langages de programmation et fournit diverses extensions via Marketplace. Ses avantages incluent le léger, l'évolutivité, le support linguistique étendu, les fonctionnalités riches et la version

Comment exécuter le code Java dans le bloc-notes Comment exécuter le code Java dans le bloc-notes Apr 16, 2025 pm 07:39 PM

Bien que le bloc-notes ne puisse pas exécuter directement le code Java, il peut être réalisé en utilisant d'autres outils: à l'aide du compilateur de ligne de commande (Javac) pour générer un fichier bytecode (filename.class). Utilisez l'interpréteur Java (Java) pour interpréter ByteCode, exécuter le code et sortir le résultat.

Quel est le but principal de Linux? Quel est le but principal de Linux? Apr 16, 2025 am 12:19 AM

Les principales utilisations de Linux comprennent: 1. Système d'exploitation du serveur, 2. Système intégré, 3. Système d'exploitation de bureau, 4. Environnement de développement et de test. Linux excelle dans ces domaines, offrant des outils de stabilité, de sécurité et de développement efficaces.

Comment vérifier l'adresse de l'entrepôt de Git Comment vérifier l'adresse de l'entrepôt de Git Apr 17, 2025 pm 01:54 PM

Pour afficher l'adresse du référentiel GIT, effectuez les étapes suivantes: 1. Ouvrez la ligne de commande et accédez au répertoire du référentiel; 2. Exécutez la commande "git Remote -v"; 3. Affichez le nom du référentiel dans la sortie et son adresse correspondante.

See all articles