Je me demande si des variables constantes statiques sont du thread-coffre-fort ou non?
Exemple de code SNIPPET: P>
void foo(int n)
{
static const char *a[] = {"foo","bar","egg","spam"};
if( ... ) {
...
}
}
5 Réponses :
Dans votre exemple, le pointeur lui-même peut être considéré comme un fil de sécurité. Il sera initialisé une fois et ne sera pas modifié plus tard. p>
Cependant, le contenu de la mémoire pointée ne sera pas du tout. p>
En supposant qu'aucune erreur de programmation provoque une mise sur pied ou sous-courue de la mémoire tampon, quelle est la prémisse de la mémoire ne faisant pas de thread-coffre-fort?
L'accès simultané à une ressource partagée (dans ce cas, la mémoire) peut conduire à une corruption ou de comportement indésirable. Pour éviter ce type de problème, l'accès à cette ressource doit être sérialisé d'une manière ou d'une autre. Cela peut généralement être atteint en utilisant des mutiles ou des objets de niveau supérieur tels que la section critique. Pour plus d'informations, voici quelques informations intéressantes: C2.com/cgi/wiki?Trireadsafe A> EN.Wikipedia.org/wiki/Trhead_Safety
Les pointeurs peuvent être modifiés i>. Les caractères des chaînes réelles ne peuvent pas.
C'est seulement l'écriture. Les threads multiples peuvent lire simultanément tout bloc de mémoire donné sans problème. Dans ce cas, si toutes les données sont constituées (le pointeur et le contenu), il n'y a pas de problème de sécurité de thread - s'il garantit qu'il n'est que initialisé une fois.
-1 const FOO * signifie que le pointeur pointe vers un foo qui ne peut pas être changé, pas i> que le pointeur lui-même ne peut pas être changé.
Dans cet exemple, , qu'il s'agisse de comme une note latérale, c'est généralement une mauvaise idée de déclarer des tableaux des pointeurs à des cordes constantes, en particulier dans le code qui pourraient être utilisés dans des bibliothèques partagées, car il aboutit à de nombreuses relocalisations et que les données ne peuvent pas être localisées dans des sections constantes. Une topique bien meilleure est la suivante: p> où 5 a été choisi de telle sorte que toutes vos cordes s'adaptent. Si les chaînes sont de longueur variable et que vous n'avez pas besoin d'y accéder rapidement (par exemple, si elles sont des messages d'erreur pour une fonction, comme et vous pouvez accéder à la chaîne Notez que La finale A code> n'est pas const code>. C'est un éventail de pointeurs à const code> cordes. Si vous voulez faire A code> elle-même const code>, vous avez besoin de: const code> ou Pas, c'est strError code> pour revenir), puis les stocker comme ceci est le plus efficace : p> n code> th avec: p> \ 0 code> est importante. Il provoque la chaîne d'avoir deux 0 octets à la fin, arrêtez ainsi la boucle si n code> est hors limites. Sinon, vous pouvez vérifier n code> à l'avance. P> p>
Pourquoi les compilateurs ne peuvent-ils pas mettre de telles données dans des sections constantes? Les valeurs bit-for-for-bit des éléments de matrice ne seront pas connues tant que le temps de charge, mais le chargeur ne doit pas avoir de problèmes de remplissage de choses. Est-ce que le problème avec des systèmes qui s'attendent à ce que des sections constantes soit remboursable, même pendant l'exécution du code?
Je n'appelle pas cela une section constante si elle est modifiée par le chargeur à temps de charge. Il encourt une mémoire physique frappée pour chaque processus qui utilise la bibliothèque et des frais généraux de charge importants. Par des sections constantes réelles, je voulais dire des images cartographiées par la mémoire partagée du fichier de bibliothèque réelle sur le disque. Si vous pensez que je devrais clarifier cela dans la réponse, je le ferai.
Pour être vraiment en sécurité, vous devriez faire p>
Ceci inhibe la modification des données BTW, je préfère écrire le Statique Char Const * const a [] code> p>
Const code> après que le nom typique soit clair à un premier coup d'œil sur l'endroit où le const code> s'applique, nommément à gauche. p>
Bon commentaire. Vous semblez impliquer que ce sera sur le thread-coffre-fort s'il écrit les deux const am je corrigez?
Toute variable jamais modifiée, que cela soit explicitement déclaré comme const, est intrinsèquement thread-coffre-fort. P>
const code> n'est pas une garantie du compilateur qu'une variable est immuable. Const code> est une promesse que vous em> apportez au compilateur qu'une variable ne sera jamais modifiée. Si vous revenez sur cette promesse, le compilateur générera une erreur qui vous dirigera, mais vous pouvez toujours faire taire le compilateur en moulant la consension. P>
Statique const Char * A [] = {"FOO", "Bar", "Egg", "Spam"}; P> blockQuote>
en C ce qui serait toujours du fil sûr: les srétures seraient déjà créées lors de la compilation, aucune action supplémentaire n'est prise au moment de l'exécution, aucune condition de course n'est possible. P>
Attention à la compatibilité C ++ cependant. L'objet Static Const serait initialisé sur la première entrée dans la fonction, mais l'initialisation n'est pas garantie de la sécurité de la langue. Iow Ceci est ouvert à une condition de course lorsque deux threads différents entrent dans la fonction simultanément et tentent d'initialiser l'objet en parallèle. P>
Mais même en C ++, POD (données anciennes simples: Les structures n'utilisant pas de fonctions C ++, telles que dans votre exemple) se comporteraient de la manière compatible C. p>
À tout moment, l'un des threads pourrait faire E.g a [0] = "FAA" code>, donc non, il ne s'agit que de threadsafe si vous donnez des garanties supplémentaires, mais ce n'est pas threadsafe en soi.
@Jens Gustedt: True, mais ma lecture de la question est de savoir si l'initialisation est la sécurité du fil. L'initialisation est. Utilisation - Les règles habituelles s'appliquent.