8
votes

C Global Static - partagé entre les threads?

en C, déclarant une variable statique de la portée globale en fait une variable globale. Est-ce que cette variable globale partagée entre les threads ou est-elle allouée par thread?

mise à jour: S'ils sont partagés entre les threads, quel est un moyen facile de faire des globaux dans une bibliothèque préexistante unique à un fil / non partagé?

mise à jour2: Fondamentalement, j'ai besoin d'utiliser une bibliothèque C préexistante avec des globaux de manière filable.


5 commentaires

Déclarer une variable statique en fait une variable de portée de fichier. La déclarant non statique le rend global.


Merci pour cette précision.


Quel système d'exploitation utilisez-vous? Je pense qu'il pourrait y avoir une solution spécifique à la plate-forme pour la mise à jour2.


Dev / Débogage sous Windows. Déploiement sur Linux.


@Williampursell Je ne dirais pas "la déclarer non statique", je dirais "ne pas la déclarer statique".


3 Réponses :


19
votes

Il est visible pour l'ensemble du processus, c'est-à-dire tous les discussions . Bien sûr, cela est en pratique. En théorie, vous ne pouviez pas dire parce que les threads n'ont rien à voir avec la norme C (au moins jusqu'à C99, qui est la norme qui était en vigueur lorsque cette question a été posée).

Mais toutes les bibliothèques de fil que j'ai jamais utilisé aurait des globaux accessibles à tous les filets.


mise à jour 1:

De nombreuses bibliothèques de fil (Pthreads, pour une) vous permettront de Créez des données spécifiques à thread, un moyen pour les fonctions pour créer et utiliser des données spécifiques au thread sans qu'il soit transmis à travers la fonction.

Donc, par exemple, une fonction pour renvoyer des nombres aléatoires pseudo-aléatoires peut vouloir chacun fil d'avoir une graine indépendante. Donc, chaque fois qu'il est appelé, cela crée ou se fixe à un bloc spécifique au fil tenant cette graine (en utilisant une sorte de touche).

Ceci permet aux fonctions de maintenir la même signature que les non-filetées ( IMPORTANT S'ils sont des fonctions ISO C par exemple) car l'autre solution implique l'ajout d'un pointeur spécifique au thread à l'appel de fonction elle-même.

Une autre possibilité est d'avoir une gamme de globaux dont chaque thread obtient < em> un , tel que: xxx

Ceci permettrait à la fonction de thread à raconter la variable globale de la matrice. < P> Il existe d'autres méthodes, sans doute, mais à connaître votre environnement cible, il n'y a pas beaucoup de point dans les discussions.


Mise à jour 2:

Le moyen le plus simple d'utiliser une bibliothèque sans fil de sécurité dans un environnement fileté consiste à fournir des appels d'enveloppe avec une protection mutex.

Par exemple, dites que votre bibliothèque a un non thread-coffre-fort dothis () fonction. Ce que vous faites est de fournir une enveloppe pour cela: xxx

Qu'est-ce qui se passera là-bas est qu'un seul fil à la fois sera en mesure de réclamer le mutex (et d'appeler le non fonction de sécurité-sécurité). D'autres seront bloqués jusqu'à ce que l'actuel revienne.


7 commentaires

Merci. Question mise à jour un peu.


C'est bon, James, je pense que je suis en train de suivre maintenant :-)


Mutex n'est pas toujours une option, car la bibliothèque pourrait stocker des données temporaires dans des variables globales entre plusieurs appels d'une seule fonction. Par exemple. pour calculer la variance de certaines variables.


C'est un bon point, @kirill, mais vous pouvez simplement déplacer la sérialisation mutex dans la hiérarchie d'exécution, par exemple, startdothis (), mydothis (), mydothis (), ..., stopdothis (), avec la revendication mutex dans Startdothis () et libération dans stopdothis (). Mais, à ce moment-là, j'irais probablement chercher une meilleure bibliothèque ou écrir mon propre :-)


Si vous avez accès à la source de la bibliothèque, il serait préférable d'écrire la classe enveloppée et de déplacer toutes les variables mondiales. Si vous n'avez pas accès aux sources, vous ne pouvez pas savoir à quel niveau de hiérarchie d'exécution que vous pourriez utiliser mutex.


J'ai ces questions suivantes: 1. Les variables statiques sont-elles stockées sur la pile elle-même similaire à celle des globaux? Si tel est le cas, comment sont-ils protégés pour ne permettre que l'accès de la classe locale? 2. Dans un contexte multi-threadé, la peur que cette mémoire puisse être consultée directement par d'autres threads / noyau? Ou pourquoi pouvons-nous utiliser static / global dans un environnement multi-processus / thread?


@Swapna, qui aurait probablement été mieux comme une nouvelle question, mais: (1) non, les threads ont généralement leur propre pile. (2) Non, ce n'est pas l'utilisation de la mémoire qui est le problème, c'est le fait que le filetage A peut essayer de l'utiliser à mi-chemin de la mise à jour par le thread b (I.e., Ehen C'est dans un état incohérent).



1
votes

standard C / C ++ ne prend pas en charge les threads. Donc, toutes les variables partagées entre les threads. Support de thread Mise en œuvre dans la bibliothèque C / C ++ Runtime qui ne fait pas partie de la norme. L'exécution est spécifique pour chaque implémentation de C / C ++. Si vous souhaitez écrire un code portable dans C ++, vous pouvez utiliser Boost Interprocess Bibliothèque .

Pour déclarer une variable locale de fil dans Microsoft Visual Studio, vous pouvez utiliser Microsoft spécifique mot-clé __ DeclSpec (thread) .


0 commentaires