Étant donné un programme composé de variables et d'instructions qui modifient ces variables, et une primitive de synchronisation (un moniteur, un mutex, un java synchronisé ou un verrou C #), est-il possible de prouver qu'un tel programme est thread-safe?
Existe-t-il même un modèle formel pour décrire des choses comme la sécurité des fils ou les conditions de course?
Réponses:
Il est difficile de prouver qu'un programme est "thread-safe". Il est cependant possible de définir concrètement et formellement le terme «course aux données». Et il est possible de déterminer si une trace d'exécution d'une exécution spécifique d'un programme a ou non une course de données dans le temps proportionnelle à la taille de la trace. Ce type d'analyse remonte au moins à 1988: Barton P. Miller, Jong-Deok Choi, «A Mechanism for Efficient Debugging of Parallel Programs», Conf. sur Prog. Lang. Dsgn. et Impl. (PLDI-1988): 135-144 .
Étant donné la trace d'une exécution, nous définissons d'abord un ordre partiel qui se produit avant les événements dans la trace. Étant donné deux événements et b qui se produisent sur le même thread, alors a < b ou . (Les événements sur le même thread forment un ordre total donné par la sémantique séquentielle du langage de programmation.) Les événements de synchronisation (il peut s'agir d'acquisitions et de sorties de mutex, par exemple), donnent un inter-thread supplémentaire qui se produit avant l'ordre partiel. (Si le thread libère un mutex et que le thread acquiert ce mutex, nous disons que la libération a lieu avant l'acquisition.)une b a < b b < a S T
Puis, étant donné deux accès aux données (lecture ou écriture sur des variables qui ne sont pas des variables de synchronisation) et qui sont au même emplacement de mémoire, mais par des threads différents et où ou est une opération d'écriture, nous disons qu'il y a une donnée- course entre et si ni ni .une b une b une b a < b b < a
La norme C ++ 11 est un bon exemple. (La section appropriée est 1.10 dans les spécifications provisoires disponibles en ligne.) C ++ 11 fait la distinction entre les objets de synchronisation (mutex et variables déclarées avec un
atomic<>
type) et toutes les autres données. La spécification C ++ 11 indique que le programmeur peut raisonner sur les accès aux données sur une trace d'un programme multithread comme s'il était séquentiellement cohérent si les accès aux données sont tous sans course de données.L'outil Helgrind (qui fait partie de Valgrind) effectue ce type de détection basée sur les données avant que ne le fassent plusieurs outils commerciaux (par exemple, Intel Inspector XE.) Les algorithmes des outils modernes sont basés sur la conservation d'horloges vectorielles associées à chaque thread et à la synchronisation. objet. Je pense que cette technique d'utilisation d'horloges vectorielles pour la détection de la race des données a été lancée par Michiel Ronsse; Koen De Bosschere: "RecPlay: un système d'enregistrement / relecture pratique entièrement intégré", ACM Trans. Comput. Syst. 17 (2): 133-152, 1999 .
la source
Du côté pratique, il existe un système de vérification VCC qui peut être utilisé pour prouver formellement la sécurité des threads des programmes C.
Ceci est une citation du site web:
la source
Il s'agit d'un domaine très difficile à assurer l'exactitude du programme en ce qui concerne l'exclusion des conditions de course, une sorte de "talon d'Achille" de traitement parallèle. La meilleure approche pour l'exactitude du programme est généralement d'éviter les primitives de bas niveau et de travailler avec des modèles de conception de plus haut niveau (par exemple à partir de bibliothèques) qui assurent la synchronisation des threads. Il existe un modèle CSP, communiquant des processus séquentiels par Hoare, qui a des preuves de justesse étant donné que les développeurs se limitent au "framework". Il a une certaine similitude conceptuelle et une origine / chevauchement chronologique avec les "tuyaux et filtres" Unix bien que nous n'ayons pas (encore?) Trouvé de lien direct entre les deux.
Deux autres cadres qui tentent d'améliorer la correction de la parallélisation par des modèles de conception, et qui ont la plupart des algorithmes / modèles de conception standard / connus à cet effet:
la source