Qu'est-ce qu'une condition de course ?

0
204
Juice Dash/Shutterstock.com

Avoir avez-vous déjà couru une course? Si oui, vous savez déjà qu'une photo finish est parfois nécessaire pour désigner le gagnant ! Mais que se passe-t-il si deux personnes arrivent en même temps à la ligne d'arrivée ? Bienvenue dans les conditions de concurrence.

Que sont les fils informatiques ?

Pour expliquer une condition de concurrence, nous doivent d'abord comprendre un peu comment les ordinateurs fonctionnent en interne. Lorsque vous utilisez un système d'exploitation, vous effectuerez diverses actions telles que l'ouverture d'une fenêtre de terminal de commande, l'ouverture d'un navigateur, etc. Chacune de ces actions entraînera une réaction du système d'exploitation pour démarrer un nouveau thread informatique/informatique.

Un thread est un processus informatique/informatique qui exécutera/exécutera les différentes étapes (étapes de programmation, écrites à l'origine au format du code source et régulièrement compilées par un compilateur) nécessaires à l'exécution de la tâche que vous avez demandé au système d'exploitation ou au logiciel qui l'exécute. .

Sous Linux, un tel thread est identifié de manière unique par un PID (Process Identifier). Pour en savoir plus sur les PID dans Linux, vous pouvez lire nos articles Bash Automation and Scripting Basics (Part 3) et How Linux Signals Work: SIGINT, SIGTERM et SIGKILL.

Sous Windows, un thread est également identifié de manière unique par un ID de processus (voir la colonne PID dans le Gestionnaire des tâches de Windows), bien que la mise en œuvre de la gestion du processus soit différente entre Linux et Windows ; code sous-jacent différent, différents outils d'interaction PID, etc. et compatibilité limitée. De plus, l'ID de processus Windows PID ne doit pas être confondu avec l'ID de produit PID (même terme, signification différente) ou VID(Fournisseur ID). Les deux derniers se réfèrent à l'identification des périphériques et ne sont pas liés à la gestion des processus.

Quand un thread démarre, il peut en lui-même démarrer d'autres threads. Le thread d'origine est souvent appelé thread principal ou thread parent. Par exemple, lorsque vous cliquez sur l'icône de votre navigateur Web préféré, il démarre immédiatement un fil (le fil principal), et ce fil démarre très rapidement plusieurs sous-fils, ou fils enfants, et devient ainsi le fil parent.

Publicité

Vous pouvez également penser à des sujets tels que les coureurs dans une course. Par exemple, pensez à un serveur de base de données occupé servant de nombreux clients connectés différents. Chacun de ces threads clients (notez l'utilisation du mot thread) aura (dans de nombreux cas) en soi au moins un thread sur le serveur hôte de la base de données et/ou à l'intérieur du logiciel de base de données lui-même (c'est-à-dire deux threads, un connecté dans le système d'exploitation et un dans le logiciel de base de données).

Le serveur de base de données essaie de servir tous ces threads en même temps – d'où le terme processus simultanés ou threads simultanés et s'il y a des bogues dans le logiciel de base de données (ou le système d'exploitation, etc.), tôt ou tard, il peut se retrouver dans une situation de concurrence.

Qu'est-ce qu'une condition de course ?

Un moyen simple de faire le lien avec les coureurs participant à une course est d'imaginer une photo d'arrivée où deux coureurs franchissent réellement la ligne d'arrivée au même moment. Il est possible, bien que peu probable, que cela se produise chez les races humaines. Pour les ordinateurs qui traitent des milliers d'opérations par milliseconde, cela devient beaucoup plus faisable.

En tant qu'autre exemple, imaginez une course de relais où les coureurs passent un bâton (le bâton de couleur flashy) d'une personne à l'autre. Imaginez maintenant qu'un des participants à la course fait une erreur, et il y a maintenant deux coureurs qui pensent qu'ils devraient obtenir le bâton de couleur rouge.

Un événement important dans une course de relais est le passage du témoin, car cela peut signifier que l'ancien détenteur du témoin peut arrêter de courir, et il appartient maintenant au nouveau propriétaire de faire de son mieux. Il y a maintenant deux coureurs qui prennent le relais. Ce sera une situation intéressante à regarder à la télévision (si vous aimez ce genre de choses), mais il est clair qu'il y aura des retombées.

Essentiellement, une condition de concurrence est un bogue, une erreur ou une faille dans le code du système informatique qui produit des résultats imprévisibles : une séquence d'événements inattendue. Cela est normalement causé par deux threads en conflit d'une manière ou d'une autre, plus de deux threads peuvent être impliqués dans le conflit réel, et souvent plus de deux threads s'exécutent dans le logiciel défaillant.

Publicité

Dans notre exemple de race humaine, nous avons eu deux personnes accédant à un objet à peu près au même moment, et la corruption(un terme informatique pour indiquer que certaines données ont été corrompues, où de telles données pourraient résider en mémoire ou sur disque ou dans le processeur, etc.) s'est produit au moment où deux personnes (ou deux fils en analogie informatique) ont essayé saisir le bâton et le conflit s'est produit. En termes informatiques, deux threads ont essayé d'écrire un espace mémoire qui ne devrait normalement être écrit que par un seul thread (un runner).

Les conditions de course peuvent survenir dans divers domaines comme l'électronique à l'intérieur, les logiciels informatiques et la vie en général. Par exemple, une collision d'appels est un terme de télécommunications pour décrire la situation dans laquelle un canal de communication est saisi aux deux extrémités simultanément. À l'intérieur du logiciel informatique – l'un des domaines les plus importants des conditions de course – il existe une grande variété de conditions de concurrence possibles.

En tant qu'autre exemple de condition de concurrence dans un logiciel informatique, imaginez deux threads de calcul fonctionnant avec un espace mémoire donné. Un utilisateur vient de valider un formulaire et le logiciel principal écrit ce formulaire en mémoire. Simultanément, un autre utilisateur lit les champs de ce formulaire dans le même espace mémoire. En fonction de ce qui se passe, l'utilisateur lecteur peut recevoir un formulaire partiellement incorrect avec des informations partiellement mises à jour.

Prévention des conditions de concurrence : Sécurité des threads

Il y a eu beaucoup de discussions sur les conditions de concurrence dans l'industrie informatique. Selon le langage de codage que vous utilisez, il peut y avoir de nombreuses ou peu de dispositions pour gérer les conditions de concurrence. Un terme souvent utilisé est thread safety ou une application thread safe ou un langage de programmation [construire]. Ces termes sont utilisés pour indiquer si un morceau de code ou un logiciel dans son ensemble est thread safe, c'est-à-dire écrit de manière à éviter et même empêcher les conditions de concurrence.

Si le logiciel est considéré comme thread safe, il est réputé exempt de toute possibilité de conditions de concurrence . Dans de nombreux cas, ‘estimé‘ thread-safe est ce que les développeurs peuvent offrir de mieux, et d'autant plus lorsque de nombreux threads et interactions sont possibles. La complexité de nombreux threads fonctionnant avec de nombreuses ressources peut facilement devenir une myriade de gestion de code et une myriade encore plus grande de conditions de concurrence possibles.

Diverses constructions de programmation peuvent être utilisées pour empêcher les conditions de concurrence. Par exemple, les sémaphores et les mutex. La complexité de l'utilisation de telles constructions dépendra du langage de programmation utilisé et de leur prise en charge native pour une meilleure gestion des threads. Par exemple, en C++, on peut regarder la classe std::mutex pour implémenter un verrou mutex (c'est-à-dire mutuellement exclusif). Dans Bash, cependant, on ne trouve pas une telle construction nativement.

Publicité

En allant plus loin, on peut également considérer quelles constructions, fonctions ou même exécutables et bibliothèques sont déjà thread-safe, puis utiliser ces constructions, fonctions, exécutables et bibliothèques comme base pour créer une nouvelle construction, fonction, exécutable, bibliothèque , ou un progiciel complet.

Mettre en œuvre des constructions de gestion de thread-safe, même de base, peut être une question complexe. Par exemple, considérons la difficulté d'implémenter un sémaphore dans Bash.

Résumé

Dans cet article, nous avons exploré les fils de calcul et conditions de course. Nous avons examiné des analogies avec les courses à pied et les courses de relais dans la vie humaine pour explorer certaines conditions de course de base qui peuvent se produire à l'intérieur des ordinateurs. Enfin, nous avons exploré la sécurité des threads, les différentes implémentations de la gestion des conditions de concurrence dans les langages de codage informatique et la manière dont nous pouvons empêcher les conditions de concurrence.

Si vous avez aimé cet article, jetez un œil à Comment fonctionnent les portes logiques : OU , ET, XOR, NOR, NAND, XNOR et NOT article.