10
votes

Sont des variables Cons-un-stages statiques?

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( ... ) {
       ...
      }
}


0 commentaires

5 Réponses :


6
votes

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.

Cependant, le contenu de la mémoire pointée ne sera pas du tout.


5 commentaires

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 EN.Wikipedia.org/wiki/Trhead_Safety


Les pointeurs peuvent être modifiés . 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 que le pointeur lui-même ne peut pas être changé.



3
votes

Dans cet exemple, A n'est pas const . C'est un éventail de pointeurs à const cordes. Si vous voulez faire A elle-même const , vous avez besoin de: xxx

, qu'il s'agisse de const ou Pas, c'est toujours sûr de lire des données de plusieurs threads si vous n'écrivez à aucun d'entre eux.

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: xxx

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 strError pour revenir), puis les stocker comme ceci est le plus efficace : xxx

et vous pouvez accéder à la chaîne n th avec: xxx

Notez que La finale \ 0 est importante. Il provoque la chaîne d'avoir deux 0 octets à la fin, arrêtez ainsi la boucle si n est hors limites. Sinon, vous pouvez vérifier n à l'avance.


2 commentaires

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.



13
votes

Pour être vraiment en sécurité, vous devriez faire

Statique Char Const * const a []

Ceci inhibe la modification des données et tous les pointeurs de la table à modifier.

BTW, je préfère écrire le Const après que le nom typique soit clair à un premier coup d'œil sur l'endroit où le const s'applique, nommément à gauche.


1 commentaires

Bon commentaire. Vous semblez impliquer que ce sera sur le thread-coffre-fort s'il écrit les deux const am je corrigez?



17
votes

Toute variable jamais modifiée, que cela soit explicitement déclaré comme const, est intrinsèquement thread-coffre-fort.

const n'est pas une garantie du compilateur qu'une variable est immuable. Const est une promesse que vous 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.


0 commentaires

3
votes

Statique const Char * A [] = {"FOO", "Bar", "Egg", "Spam"};

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.

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.

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.


2 commentaires

À tout moment, l'un des threads pourrait faire E.g a [0] = "FAA" , 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.