Article de reference

Sécurité du fil

En programmation multithread , une fonction est dite thread-safe lorsqu'elle peut être appelée ou accédée simultanément par plusieurs threads sans provoquer de comportement inat...

En programmation multithread , une fonction est dite thread-safe lorsqu'elle peut être appelée ou accédée simultanément par plusieurs threads sans provoquer de comportement inattendu, de conditions de concurrence ou de corruption de données . Dans le contexte multithread où un programme exécute plusieurs threads simultanément dans un espace d'adressage partagé et où chaque thread a accès à la mémoire de tous les autres , les fonctions thread-safe doivent garantir que tous ces threads se comportent correctement et respectent leurs spécifications de conception sans interaction non intentionnelle.

Il existe différentes stratégies pour créer des structures de données thread-safe.

conditions de concurrence lorsque ces ressources sont accédées simultanément par plusieurs threads.
  • Sécurité multithread, sécurité MT : Utilise un mutex pour chaque ressource afin de garantir que le thread est exempt de conditions de concurrence lorsque ces ressources sont accédées simultanément par plusieurs threads.
  • Les garanties de sécurité des threads incluent généralement des mesures de conception visant à prévenir ou limiter le risque de différents types d' interblocages , ainsi que des optimisations pour maximiser les performances concurrentes. Cependant, l'absence totale d'interblocages ne peut être garantie, car ces derniers peuvent être provoqués par des rappels et des violations de l'architecture en couches, indépendamment de la bibliothèque elle-même.

    Les bibliothèques logicielles peuvent offrir certaines garanties de sécurité des threads. Par exemple, les lectures concurrentes peuvent être garanties comme étant sûres dans un contexte multithread, mais pas les écritures concurrentes. La sécurité des threads d'un programme utilisant une telle bibliothèque dépend de sa capacité à utiliser cette bibliothèque conformément à ces garanties.

    Approches de mise en œuvre

    Voici deux catégories d'approches permettant d'éviter les conditions de concurrence afin de garantir la sécurité des threads.

    La première catégorie d'approches vise à éviter le partage d'état et comprend :

    Réentrée
    Écrire du code de manière à ce qu'il puisse être partiellement exécuté par un thread, entièrement exécuté par ce même thread, ou simultanément exécuté par un autre thread tout en menant à bien l'exécution initiale. Cela nécessite la sauvegarde des informations d'état dans des variables locales à chaque exécution, généralement sur une pile, plutôt que dans des variables statiques , globales ou autres états non locaux. Tous les états non locaux doivent être accessibles par des opérations atomiques et les structures de données doivent être réentrantes.
    stockage local au thread
    Les variables sont localisées de sorte que chaque thread possède sa propre copie privée. Ces variables conservent leurs valeurs entre les sous-routines et autres limites de code et sont thread-safe car elles sont locales à chaque thread, même si le code qui y accède peut être exécuté simultanément par un autre thread.
    Objets immuables
    L'état d'un objet ne peut être modifié après sa création. Cela implique que seules des données en lecture seule sont partagées et que la sécurité intrinsèque des threads est assurée. Les opérations mutables (non constantes) peuvent alors être implémentées de manière à créer de nouveaux objets au lieu de modifier les objets existants. Cette approche est caractéristique de la programmation fonctionnelle et est également utilisée par les implémentations de chaînes de caractères en Java, C# et Python . (Voir Objet immuable .)

    La seconde catégorie d'approches est liée à la synchronisation et est utilisée dans les situations où un état partagé ne peut être évité :

    Exclusion mutuelle
    L'accès aux données partagées est sérialisé à l'aide de mécanismes garantissant qu'un seul thread puisse lire ou écrire sur ces données à la fois. L'intégration de l'exclusion mutuelle doit être soigneusement étudiée, car une utilisation inappropriée peut entraîner des effets indésirables tels que des interblocages , des blocages persistants et une pénurie de ressources .
    opérations atomiques
    L'accès aux données partagées s'effectue par des opérations atomiques non interrompables par d'autres threads. Ceci requiert généralement l'utilisation d'instructions machine spécifiques , disponibles dans une bibliothèque d'exécution . Grâce à l'atomicité des opérations, les données partagées restent toujours valides, quel que soit l'accès qu'elles reçoivent d'autres threads. Les opérations atomiques sont à la base de nombreux mécanismes de verrouillage de threads et servent à implémenter les primitives d'exclusion mutuelle.

    Exemples

    Dans l'extrait de code Java suivant, le mot-clé Java synchronized rend la méthode thread-safe :

    langage C , chaque thread possède sa propre pile. Cependant, une variable statique n'est pas stockée sur la pile ; tous les threads y ont un accès simultané. Si plusieurs threads exécutent simultanément la même fonction, il est possible qu'une variable statique soit modifiée par un thread pendant qu'un autre est en train de la vérifier. Cette erreur logique , difficile à diagnostiquer et qui peut compiler et s'exécuter correctement la plupart du temps, est appelée condition de concurrence . Une méthode courante pour l'éviter consiste à utiliser une autre variable partagée comme « verrou » ou « mutex » (pour exclusion mutuelle ) .

    Dans l'extrait de code C suivant, qui appelle des en-têtes POSIX , la fonction est sûre pour les threads, mais pas réentrante :

    gestionnaire d'interruptions réentrant et qu'une seconde interruption survient pendant que le mutex est verrouillé, la seconde routine restera bloquée indéfiniment. Comme le traitement des interruptions peut en désactiver d'autres, l'ensemble du système risque d'être affecté.

    La même fonction peut être implémentée pour être à la fois sûre pour les threads et réentrante en utilisant les atomiques sans verrou , qui ont été introduites dans C++11 :

    Plus d articles de Worldlex Wiki

    Revenez a l index pour explorer davantage de pages sur l histoire, la science, la culture, la geographie et la societe en francais.

    Explorer l index