170 votes

Qu'est-ce qui rend une méthode thread-safe? Quelles sont les règles?

Sont dans l'ensemble des règles/lignes directrices pour ce qui fait une méthode thread-safe? Je comprends qu'il y a probablement un million de situations particulières, mais qu'en est-il général? C'est ce simple?

  1. Si une méthode n'accède variables locales, c'est thread-safe.

Est ce que c'est? Cela s'applique pour les méthodes statiques?

Une seule réponse, fournie par @Cybis, était: "les variables Locales ne peuvent pas être partagées entre les threads, car chaque thread possède sa propre pile." Est-ce le cas pour les méthodes statiques?

Si une méthode est passé d'un objet de référence, ne fait que briser la sécurité des threads? J'ai fait quelques recherches, et il y a beaucoup à propos de certains cas, mais je m'attendais à être en mesure de définir, par l'utilisation d'un certain nombre de règles, de lignes directrices à suivre pour s'assurer qu'une méthode est thread-safe.

Donc, je suppose que ma question ultime est: "Est-il une courte liste de règles qui définissent un" thread-safe " méthode? Si oui, quels sont-ils?"

** EDIT **

Beaucoup de bons points ont été faites ici. Je pense que la vraie réponse à cette question est: "Il n'y a pas de règles simples pour assurer la sécurité des threads." Cool. Des beaux. Mais en général, je pense que l'on a accepté la réponse fournit un bien, un court résumé. Il y a toujours des exceptions. Ainsi soit-il. Je peux vivre avec ça.

147voto

Trevor Pilley Points 7304

Si une méthode (instance ou statique), seules les références variables étendues à l'intérieur de cette méthode, puis elle est thread-safe, car chaque thread possède sa propre pile:

Dans ce cas, plusieurs threads peuvent appeler ThreadSafeMethod simultanément sans problème.

public class Thing
{
    public int ThreadSafeMethod(string parameter1)
    {
        int number; // each thread will have its own variable for number.
        number = parameter1.Length;
        return number;
    }
}

Cela est également vrai si les appels de méthode autre méthode de la classe qui seule référence configuré localement des variables:

public class Thing
{
    public int ThreadSafeMethod(string parameter1)
    {
        int number;
        number = this.GetLength(parameter1);
        return number;
    }

    private int GetLength(string value)
    {
        int length = value.Length;
        return length;
    }
}

Si une méthode accède à tous (état de l'objet) des propriétés ou des champs (instance ou statique), alors vous avez besoin d'utiliser des verrous pour s'assurer que les valeurs ne sont pas modifiées par un autre thread.

public class Thing
{
    private string someValue; // all threads will read and write to this same field value

    public int NonThreadSafeMethod(string parameter1)
    {
        this.someValue = parameter1;

        int number;

        // Since access to someValue is not synchronised by the class, a separate thread
        // could have changed its value between this thread setting its value at the start 
        // of the method and this line reading its value.
        number = this.someValue.Length;
        return number;
    }
}

Vous devez être conscient que tous les paramètres passés à la méthode qui n'est ni une structure ou immuable pourraient être muté par un autre thread en dehors de la portée de la méthode.

Pour assurer une bonne simultanéité vous avez besoin d'utiliser le verrouillage.

pour plus d'informations, voir l' instruction lock référence C# et ReadWriterLockSlim.

verrou est surtout utile pour apporter un à la fois la fonctionnalité, ReadWriterLockSlim est utile si vous avez besoin de plusieurs lecteurs, et seul des écrivains.

115voto

Eric Lippert Points 300275

Si une méthode n'accède variables locales, c'est thread-safe. Est ce que c'est?

Absolultely pas. Vous pouvez écrire un programme avec une seule variable locale accessible à partir d'un seul fil qui n'est pourtant pas thread-safe:

http://stackoverflow.com/a/8883117/88656

Cela s'applique pour les méthodes statiques?

Absolument pas.

Une seule réponse, fournie par @Cybis, était: "les variables Locales ne peuvent pas être partagées entre les threads, car chaque thread possède sa propre pile."

Absolument pas. La caractéristique d'une variable locale, c'est qu'il est visible uniquement depuis l'intérieur du local de la portée, non pas que c'est allouée sur le temporaire de la piscine. C'est parfaitement légal et possible d'accéder à la même variable locale à partir de deux threads différents. Vous pouvez le faire en utilisant des méthodes anonymes, les lambdas, itérateur de blocs ou de méthodes asynchrones.

Est-ce le cas pour les méthodes statiques?

Absolument pas.

Si une méthode est passé d'un objet de référence, ne fait que briser la sécurité des threads?

Peut-être.

J'ai fait quelques recherches, et il y a beaucoup à propos de certains cas, mais je m'attendais à être en mesure de définir, par l'utilisation d'un certain nombre de règles, de lignes directrices à suivre pour s'assurer qu'une méthode est thread-safe.

Vous allez avoir à apprendre à vivre avec la déception. C'est un sujet très difficile.

Donc, je suppose que ma question ultime est: "Est-il une courte liste de règles qui définissent un" thread-safe " méthode?

Nope. Comme vous l'avez vu à partir de mon exemple plus haut une méthode vide peut être non thread-safe. Vous pourriez aussi bien demander: "est-il une courte liste de règles qui garantit une méthode est correcte". Non, il n'est pas. Fil de sécurité est rien de plus qu'un extrêmement compliqué genre de justesse.

En outre, le fait que vous êtes vous poser la question indique votre incompréhension fondamentale à propos de la sécurité des threads. Fil de sécurité est globale, et non pas un local de la propriété d'un programme. La raison pourquoi il est si difficile d'obtenir le droit est parce que vous devez avoir une connaissance complète de l'enfilage comportement de l'ensemble du programme afin d'assurer sa sécurité.

Encore une fois, regarde mon exemple: chaque méthode est trivial. C'est de cette manière que les méthodes d'interagir les uns avec les autres à un niveau "global" niveau qui rend le programme de blocage. Vous ne pouvez pas regarder de chaque méthode et de s'en débarrasser comme "sûr" et puis attendre que l'ensemble du programme est sûr, pas plus que vous pouvez en conclure que, parce que votre maison est faite de 100% non-briques creuses que la maison est également à la non-creux. La vacuité d'une maison est une propriété globale de l'ensemble de la chose, pas une somme des propriétés de ses parties.

12voto

earlNameless Points 2044

Il n'y a aucune règle dure et rapide.

Voici quelques règles pour rendre le code thread-safe .NET et pourquoi ce ne sont pas les bonnes règles:

  1. Fonction et toutes les fonctions qu'il appelle doit être pure (sans effets secondaires) et d'utiliser des variables locales. Bien que cela rendra votre code thread-safe, il y a aussi très peu de choses intéressantes que vous pouvez faire avec cette restriction .NET.
  2. Chaque fonction qui s'exerce sur un objet commun doit lock sur une chose commune. Toutes les serrures doivent être fait dans le même ordre. Cela permet de rendre le code thread-safe, mais il va incroyablement lent, et vous pourriez aussi bien ne pas utiliser plusieurs threads.
  3. ...

Il n'y a aucune règle qui rend le code thread-safe, la seule chose que vous pouvez faire est de vous assurer que votre code fonctionne, peu importe combien de fois est-il activement exécuté, chaque thread peut être interrompu à tout moment, chaque thread dans son propre état/de l'emplacement, et ce pour chaque fonction (statiques ou non) qui accède à des objets communs.

4voto

kasavbere Points 2496

Il doit être synchronisé, à l'aide d'un verrou d'objet, sans état ou immuable.

lien: http://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X