Question

Je variables globales statiques dans une bibliothèque C, qui génèrent des exceptions dans une course multithread. Je dois les rendre sûrs d'une certaine façon (à savoir, chaque fil doit se rapporter à une instance différente de ces variables). Toutes les méthodes recommandées?

Était-ce utile?

La solution

Il n'y a aucun moyen standard qui fonctionne sur toutes les implémentations de C, mais il existe des solutions spécifiques de mise en œuvre. Par exemple, avec le compilateur Microsoft (voir les docs ),

__declspec( thread ) int tls_i = 1;

marques tls_i en direct dans le stockage local des threads (chaque thread a sa propre instance distincte de cette variable). Avec gcc , la syntaxe est

__thread int tls_i;

Vous pouvez également consulter le wikipedia entrée sur le sujet.

Autres conseils

Première question:

  • les fils doivent faire leurs propres copies des variables?
  • ou doivent-ils coordonner l'accès à une seule copie partagée?

Si vous avez besoin de l'ancien, les autres réponses ont fait des suggestions au sujet de «stockage local des threads.

Si vous avez besoin de celui-ci, puis en quelque sorte ou d'une autre, vous devez vous assurer qu'il ya un mutex approprié sur ces variables (la portée du mutex est l'un des problèmes que vous faites face), et que les fils utilisent tous le mutex et la libération le mutex. Ceci est plus délicat. Il se peut même que vous devez fournir des fonctions de contrôle d'accès aux variables.

La errno variable standard peut être une lvalue modifiable:

extern int *_errno_func(void);
#define errno (*(_errno_func)())

Dans une application filetée (compilé avec -DREENTRANT), ce qui arrive; sur MacOS X, il semble être ce qui se passe de toute façon (ils utilisent le nom __error au lieu de _errno_func, les deux sont dans l'espace de la mise en œuvre)

.

Vous voudrez peut-être, ou finir par devoir, faire quelque chose de similaire pour vos variables. Le fait que vous dites qu'ils sont statiques améliore les choses un peu. Vous avez un seul fichier à traiter (sauf si vous êtes assez négligent de passer en arrière - ou - pointeurs vers ces variables).

Qu'est-ce que vous avez besoin est TLS (Thread Local Storage) , qui est également connu comme données spécifiques au thread ou données thread-privé . Ce mécanisme peut garantir à chaque fil pour accéder à sa propre copie distincte des données, sans se soucier de synchroniser l'accès à d'autres threads.


Il existe deux méthodes pour utiliser TLS:

  1. implicite: en utilisant le mot

    Windows: __declspec (thread) int tls_var = 10;

    Linux avec GCC: __thread int tls_var = 10

  2. explicite: l'utilisation spécifique TLS API connexes

    Windows:     

      TlsAlloc (): allouer de la mémoire pour les données tls
      TlsFree (): libérer la mémoire de données tls
      TlsSetValue (): set de valeur
      TlsGetValue (): get tls de tls valeur

    S'il vous plaît se référer à MSDN pour plus d'informations.

    LInux avec GCC:     

      pthread_key_create () : créer les données tls
      pthread_key_delete () : destory les données tls
      pthread_getspecific () : obtenir tls de valeur
      pthread_setspecific (): set tls de valeur
    Tournez-vous vers la page de manuel pour des informations spécifiques et détaillées.

La plupart des compilateurs ont une certaine façon de désigner le stockage local des threads. En supposant qu'il est disponible, c'est ce que vous voulez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top