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;
}
3 Réponses :
Parce qu'il modifie la graine et la graine est transmise. p>
Ceci est différent de la plupart des fonctions code> rand code> qui détiennent l'état (la graine) dans une variable globale. P> Supposons que deux threads invoquent rand_r en même temps avec la même graine de variable. P>
blockQuote> Je suppose que vous voulez dire quelque chose comme ça p> 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. P> 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é. P> p> rand_r code> 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.
Vous pouvez penser à trois niveaux de sécurité de thread, que je vais numéroter ici pour faciliter la référence. P>
1) pas du tout fil en sécurité. Il est dangereux d'appeler la fonction simultanément de plusieurs threads. Par exemple, 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, 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 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 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. p> strtok code>. P>
rand_r code>, memcpy code>. P>
pthread_mutex_lock code>. P>
rand_r code> 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é". P>
java.util.vector code> est "Safe Whlef Safe" et Java.Util.arrayList CODE> est "NON SAFFRY". Bien sûr, toutes les méthodes de java.util.arraylist code> sont au niveau 2. Un programmeur provenant de Java pourrait naturellement appeler naturellement rand_r code> et memcpy code> " pas le fil de sécurité ". P>