Il existe une différence technique importante entre les conditions de course et les courses de données. La plupart des réponses semblent supposer que ces termes sont équivalents, mais ils ne le sont pas.
Une course aux données se produit lorsque 2 instructions accèdent au même emplacement de mémoire, au moins un de ces accès est une écriture et il n'y a aucun événement avant de passer une commande parmi ces accès. Maintenant, ce qui constitue un événement avant la commande est sujet à de nombreux débats, mais en général, les paires ulock-lock sur la même variable de verrouillage et les paires de signaux d'attente sur la même variable de condition induisent un ordre passe-avant.
Une condition de concurrence est une erreur sémantique. Il s'agit d'une faille qui se produit dans le calendrier ou l'ordre des événements qui conduit à un comportement erroné du programme .
De nombreuses conditions de course peuvent être (et sont en fait) causées par des courses de données, mais ce n'est pas nécessaire. En fait, les courses de données et les conditions de course ne sont ni nécessaires ni suffisantes les unes pour les autres. Ce billet de blog explique également très bien la différence, avec un simple exemple de transaction bancaire. Voici un autre exemple simple qui explique la différence.
Maintenant que nous avons cloué la terminologie, essayons de répondre à la question initiale.
Étant donné que les conditions de concurrence sont des bogues sémantiques, il n'existe aucun moyen général de les détecter. En effet, il n'y a aucun moyen d'avoir un oracle automatisé qui puisse distinguer le comportement correct du programme incorrect dans le cas général. La détection des races est un problème indécidable.
D'un autre côté, les races de données ont une définition précise qui ne se rapporte pas nécessairement à l'exactitude, et donc on peut les détecter. Il existe de nombreuses variantes de détecteurs de course de données (détection de course de données statique / dynamique, détection de course de données basée sur un jeu de clés, détection de course de données basée sur le passé, détection de course de données hybride). Un détecteur de course de données dynamique de pointe est ThreadSanitizer qui fonctionne très bien dans la pratique.
La gestion des courses de données en général nécessite une certaine discipline de programmation pour induire des fronts entre les accès aux données partagées (soit pendant le développement, soit une fois qu'ils sont détectés à l'aide des outils mentionnés ci-dessus). cela peut être fait à travers des verrous, des variables de condition, des sémaphores, etc. Cependant, on peut également utiliser différents paradigmes de programmation comme le passage de messages (au lieu de la mémoire partagée) qui évitent les courses de données par construction.