7
votes

Si Rand_R est un vrai fil sûr?

Eh bien, la fonction RAND_R est censée être une fonction de sécurité du fil. Cependant, par sa mise en œuvre, je ne peux pas croire que cela pourrait ne pas changer par d'autres threads. Supposons que deux threads invoquent rand_r dans le même temps avec la même graine de variable. Donc, la course en lecture-écriture se produira. Le code Rand_R implémenté par GLIBC est répertorié ci-dessous. Tout le monde sait pourquoi rand_r s'appelle le fil sûr?

 int
    rand_r (unsigned int *seed)
    {
      unsigned int next = *seed;
      int result;

      next *= 1103515245;
      next += 12345;
      result = (unsigned int) (next / 65536) % 2048;

      next *= 1103515245;
      next += 12345;
      result <<= 10;
      result ^= (unsigned int) (next / 65536) % 1024;

      next *= 1103515245;
      next += 12345;
      result <<= 10;
      result ^= (unsigned int) (next / 65536) % 1024;

      *seed = next;

      return result;
    }

c c++

0 commentaires

3 Réponses :


0
votes

Parce qu'il modifie la graine et la graine est transmise.


0 commentaires

15
votes

rand_r est le fil sûr, c'est parce que la fonction est entièrement pure. Il ne lit ni ne modifie aucun état autre que les arguments. Il peut donc être appelé en toute sécurité simultanément.

Ceci est différent de la plupart des fonctions rand qui détiennent l'état (la graine) dans une variable globale.

Supposons que deux threads invoquent rand_r en même temps avec la même graine de variable.

Je suppose que vous voulez dire quelque chose comme ça xxx

qui ne signifie pas que la fonction ne soit pas en sécurité, cela signifie simplement que vous utilisez dans une voie sans fil non thread en fournissant un paramètre de sortie pouvant être accessible / modifié par un autre thread.

C'est la même chose que l'écriture de la fonction résultant d'une variable globale pouvant être accessible / modifiée par l'autre fil. Cela ne signifie pas que la fonction n'est pas la sécurité du fil, cela signifie que votre code n'est pas un fil de sécurité.


0 commentaires

20
votes

Vous pouvez penser à trois niveaux de sécurité de thread, que je vais numéroter ici pour faciliter la référence.

1) pas du tout fil en sécurité. Il est dangereux d'appeler la fonction simultanément de plusieurs threads. Par exemple, strtok .

2) Filetage sécurisé par rapport au système. Il est prudent d'appeler la fonction simultanément de plusieurs threads, à condition que les différents appels fonctionnent sur différentes données. Par exemple, rand_r , memcpy .

3) fil en toute sécurité en ce qui concerne les données. Il est prudent d'appeler la fonction simultanément à partir de plusieurs threads, même d'agir sur les mêmes données. Par exemple pthread_mutex_lock .

rand_r est au niveau 2 et la Convention dans le contexte de C (en particulier dans la spécification POSIX) consiste à appeler ce "fil de sécurité".

Dans certaines autres langues, telles que Java, la Convention est de se référer au niveau 3 comme "Safe à thread" et tout le reste comme "non fil de sécurité". Donc, par exemple java.util.vector est "Safe Whlef Safe" et Java.Util.arrayList est "NON SAFFRY". Bien sûr, toutes les méthodes de java.util.arraylist sont au niveau 2. Un programmeur provenant de Java pourrait naturellement appeler naturellement rand_r et memcpy " pas le fil de sécurité ".

en C La convention est différente, peut-être parce que les structures de données synchronisées internes sont assez rares de commencer. Dans le contexte de C, vous pourriez demander "les poignées de fichier traitent-elles-coffre-fort?", Et parlez de niveau 3, mais lorsque vous demandez "est cette fonction thread-coffre-fort?" qui signifie généralement le niveau 2.


0 commentaires