IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

[MT] Quid des variables statiques en multithread?


Sujet :

C++

  1. #1
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut [MT] Quid des variables statiques en multithread?
    Je voudrais "multithreader" un programme, mais y'a quelques variables statiques que je ne peux/veux pas ôter.
    Comment faire pour que chaque thread ait ses propres données statiques et éviter ainsi les conflits?

    J'ai vu le "Thread Local Storage" (TLS) sous Visual, mais ça m'a pas l'air applicable à d'autres systèmes.

    Vos suggestions doivent être dans la mesure du possible:
    -applicables sous différents systèmes (Windows,Linux,Unix)
    -faciles à mettre en oeuvre

    Merci par avance!

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 125
    Points : 145
    Points
    145
    Par défaut
    tu peux imaginer un classe singleton qui renvoie une instance en fonction du numero de thread

  3. #3
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    J'ai vu le "Thread Local Storage" (TLS) sous Visual, mais ça m'a pas l'air applicable à d'autres systèmes.
    C++ n'a aucune notion de multithreading, donc tout ce que tu fais dépend du système.

  4. #4
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    En C++ toute variable statique (quelle soit de portée globale ou de classe) existe une et une seule fois pour l'ensemble d'un programme.

    Donc avoir une variable statique (unique) dupliquée autant de fois qu'il y a de thread, ce n'est pas possible.

    Le meilleur moyen pour cela c'est de créer une classe qui ressemble à ce que fait un Singleton (comme là dit alskaar), mais qui se rapproche plus d'un Proxy avec allocation à la demande indexé par ton ThreadID courant (qui peut toujours être récupéré simplement quelque soit l'architecture). Pour rechercher l'association ThreadID <-> Instance Singleton, utilise un std::map.

  5. #5
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    Je sais bien tout ce que vous me dites.
    Mais je crois bien savoir qu'il existe un truc standard (probablement POSIX) qui gère les variables globales/statiques pour différents threads. Certes, c'est du C. Mais j'arrive pas à le retrouver. J'espérais que l'un d'entre vous le connaisse...

  6. #6
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    Finalement, après quelques recherches, il semble que le TLS soit intégré à la plupart des compilos (peut-être même tous).
    La syntaxe varie peut-être un peu d'un compilo à l'autre, mais rien qu'une ou deux macros ne puissent corriger.
    Je préfère utiliser le TLS plutôt que tout reprogrammer moi même...

  7. #7
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    C'est vrai que la TLS est séduisante.

    Maintenant, si sa portabilité est d'aussi bonne qualité que les pthreads & co. () ça va pas être si évident que ça !

  8. #8
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    Citation Envoyé par mchk0123
    Maintenant, si sa portabilité est d'aussi bonne qualité que les pthreads & co. () ça va pas être si évident que ça !
    Au moins le TLS est/semble intégré aux compilos.
    J'ai pas encore compilé et vérifié si ça marche, mais en tout cas sur le papier rien de plus simple.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    static __thread int tls_i; // GCC
    static __thread __declspec( thread ) int tls_i; // Visual & Intel
    Je vais déclarer une macro dans mon fichier de configuration
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #if defined(__ICL) || defined(_MSC_VER)
      //#define __thread // single-threaded
      #define __thread __declspec( thread ) //multithreaded
    #elif defined (__GNUC__)
      //#define __thread // single-threaded
    #endif
    En ce qui concerne les pthreads & co., chaque chose en son temps...

  9. #9
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 282
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 282
    Points : 11 036
    Points
    11 036
    Par défaut
    win32 -> TLS
    pthreads -> TSD (thread-Specific Data)
    Matthew Wilson, dans son Imperfect C++, les réunit sous le terme TSS (Thread-Specific Storage).

    Visiblement, il a encaspculé le tout, et je soupçonne que cela se trouve dans sa bibliothèque STLSoft.

  10. #10
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    Voilà qui devient intéressant (je ne m'était penché sur les pthreads depuis 10 ans, certains devait déjà connaître) :

    http://sources.redhat.com/pthreads-win32/

    Je ne l'ai pas testé mais cela laisse envisager une possibilité d'écrire des TLS de manière portable.

  11. #11
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Points : 1 543
    Points
    1 543
    Par défaut
    Sinon dans boost.thread il y a une partie pour gérer du 'thread specific storage', supposée portable, mais je n'ai jamais essayé de l'utiliser...

    MAT.

  12. #12
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    Visiblement avant d'être intégrer à divers compilos, il y avait une API propre à chaque système pour gérer les variables globales/statiques de chaque thread.

    Le TLS/TSD/TSS, c'est malheureusement pas encore parfait: VC8 et ICL se plaignent: "object with constructor or destructor cannot be declared 'thread'".
    C'est vraiment trop idiot. Moi qui ai 2 ou 3 maps statiques (qui gardent en mémoire des résultats intermédiaires pour ne pas avoir à tout recalculer lors des appels de fonctions suivants), il va falloir que je trouve une idée. J'ai pas l'intention d'abandonner le principe du TLS car la syntaxe est quand même pratique.
    Toute suggestion est la bien venue. Peut-être remplacer d'une manière ou d'une autre les maps par des tableaux C.

    Citation Envoyé par mchk0123
    Voilà qui devient intéressant (je ne m'était penché sur les pthreads depuis 10 ans, certains devait déjà connaître) :

    http://sources.redhat.com/pthreads-win32/
    Moi je trouvais intéressante la petite bibliothèque dont quelqu'un faisait un peu de pub dans cette discussion: http://www.developpez.net/forums/sho...d.php?t=293814
    Je l'ai pas essayé. Je sais pas si elle est portable (Windows/Unix/Linux) mais ça en a ben l'air.
    J'avais l'intention de m'en inspirer: vu que je n'ai besoin que de threads indépendants pour du calcul numérique, j'ai pas besoin de trucs compliqués (mutex, sémaphores...).

    Citation Envoyé par mchk0123
    Je ne l'ai pas testé mais cela laisse envisager une possibilité d'écrire des TLS de manière portable.
    A priori, si j'en crois les docs, le TLS est déjà portable.

    Citation Envoyé par Mat007
    Sinon dans boost.thread il y a une partie pour gérer du 'thread specific storage', supposée portable, mais je n'ai jamais essayé de l'utiliser...
    Dans la doc de la petite bibliothèque mentionnée ci dessus, j'adhère à l'argumentation suivante:
    Nous avons hésité à utilise la librairie thread du projet Boost. Cette librairie propose une implémentation C++ des threads POSIX. Par rapport à la version standard des threads POSIX écrite en C, cette version nous aurait offert certaines simplifications au niveau des opérations liées à la gestion des threads. Nous avons cependant décidé de ne pas utiliser cette librairies pour les raisons suivantes:
    - très peu d'instructions sont utilisées dans le code MPTL pour gérer les threads;
    - l'utilisation de la librairie thread de Boost implique une forte dépendance pour faire fonctionner la MPTL

  13. #13
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    Voilà, j'ai fais plusieurs essais avec le "Thread Local Storage", et malheureusement, c'est pas la panacée.

    Ca marche avec les compilos ICL et VC8 (sous réserve de ne pas rendre statique une classe avec constructeur/destructeur).
    Mais GCC 4.1.2 sous Windows n'accepte pas le TLS: "error: thread-local storage not supported for this target"

    Est-ce que vous pouvez essayer de déclarer une telle variable statique avec un GCC sous Linux/Unix ou tout autre compilateur SVP? Merci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static __thread int tls_i=0;
    Ou mieux, si quelqu'un peut me dire comment faire en sorte que ça marche avec GCC...

  14. #14
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 588
    Points
    41 588
    Par défaut
    Tu peux toujours utiliser le Thread-Local storage dynamiquement et non statiquement, avec les fonctions dédiées : Sous Windows, il s'agit de TlsAlloc(), TlsSetValue(), etc.

    Il suffit d'une variable globale ou statique qui contiendra l'index de TLS...

  15. #15
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    Citation Envoyé par Médinoc
    Tu peux toujours utiliser le Thread-Local storage dynamiquement et non statiquement, avec les fonctions dédiées : Sous Windows, il s'agit de TlsAlloc(), TlsSetValue(), etc.
    C'est l'API dont je parle un peu plus haut, mais justement je veux un programme:
    - compilable sous divers OS
    - le moins de dépendance possible vis-à-vis de librairies non standards (Boost...)
    - aussi simple que possible.

    En plus, j'ai déjà pas mal investi dans le TLS avec des changements pour récrire les classes statiques en des structures C. Ca marchait bien et puis j'ai compilé avec GCC...
    En tout cas c'est un problème de GCC, donc avec un peu de chance le problème disparaîtra de lui même dans l'avenir. C'est peut-être une option de compilation manquante, un problème lié au système, etc...

    Si quelqu'un peut tester si le TLS fonctionne sous d'autres OS que Windows, ça m'intéresse...

  16. #16
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 282
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 282
    Points : 11 036
    Points
    11 036
    Par défaut
    Dans nos projets, il y a toujours des services de base que le langage manque de nous rendre. Il ne me parait pas hallucinant d'utiliser des bibliothèques qui rendent ces sevices. Cela me parait toujours mieux que de donner dans un syndrome du NIH qui va, ici, tenter d'abstraire les diverses plateformes cibles.

    Surtout que des trucs comme boost sont suffisament devenus classiques.
    Suivant les licences, tu peux toujours regarder comment ils ont fait
    -> http://synesis.com.au/software/stlso...ss__index.html [TSS pour win32]
    -> http://synesis.com.au/software/stlso...ss__index.html [TSS pour *nix (pthread?)]
    -> http://www.boost.org/doc/html/thread_specific_ptr.html [chez boost]

  17. #17
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    Là n'est pas la question. Mais j'évite quand même les dépendances vis à vis de bibliothèques non standard. Je vois tout un tas de bonnes raisons:
    - pas toujours facile à installer, souvent laborieux même quand on connaît pas.
    - il faut les remettre à jour.
    - pas toujours compatible d'un OS à l'autre, d'un compilo à l'autre
    - il faut que chaque utilisateur de mon projet les installe
    - Quasi impensable de modifier soi même les sources de bibliothèques externes en cas de problème (ou sinon après de longues analyses), alors que modifier son propre code est si facile
    - la bibliothèque ne correspond pas forcément exactement à ce que l'on désire

    Bref je souscris à l'analyse qu'avait également fait l'auteur de la petite bibliothèque MPTL que je cite ci dessus.
    Alors je préfère programmer moi même à mon idée les quelques rares éléments dont j'ai besoin et que Boost intègre.
    J'ai rien contre Boost en particulier, mais je ne l'utiliserai pas avant qu'il ne soit livré d'office avec tout bon compilateur.

    En ce qui concerne le TLS, il semblerait que seul la version Windows de GCC ne le supporte pas, va savoir pourquoi. Mais que ça marche bien sous d'autres systèmes. Je peux faire avec. Je préfère de loin utiliser les instructions des compilos à toute bibliothèque.
    Mais j'aimerais bien que quelqu'un me confirme que ça marche sous Linux/Unix...

  18. #18
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 282
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 282
    Points : 11 036
    Points
    11 036
    Par défaut
    A partir du moment où le mot clé commence par deux underscores, je suis très méfiant..
    Alors qu'une solution qui encapsule une bibliothèque peut se reposer sur cette bibliothèque (pthread et win32 ont je pense une excellente couverture du marché à elles deux), celles qui reposent sur un mot clé propriétaire qui est dépendant de chaque compilo va AMHA être plus vite limitée (à cause du nombre de compilos différents).

    Si Matthew Wilson et d'autres auteurs (D.C.Schmidt) ont choisi de reposer sur les bibliothèques plutôt que les OS, à mon avis ce n'est pas innocent -- M.W. est le seul auteur à ma connaissance à avoir sorti un bouquin qui contient plusieurs chapitres dont le sujet est une variation de "comment faire XXX sous 15 compilos/environnements différents".

    J'avoue que je serais très curieux de savoir pourquoi s'il existe ce mot clé, ces auteurs (non des moindres) ont choisi la solution bibliothèque. Je ne trouve pas grand chosqe sur google. On dirait que c'est dû au fait que le mot clé ne soit pas présent partout (bien que très répandu à en lire http://www.open-std.org/jtc1/sc22/wg...005/n1815.html)

    Même si tu tiens absolument à réinventer la roue, tu peux regarder comment les autres roues tournent -- et je ne dis pas ça parce que je suis très méfiant (et rarement emballé par) des bibliothèques qui réiventent la roue.

    PS: le compilo de Sun semble suivre la même voie que GCC -- pardon, c'est le contraire.
    PPS: Je vois que Douglas C. Schmidt (Monsieur ACE) a écrit un article 100% orienté bibliothèque sur le sujet -> http://www.cs.wustl.edu/~schmidt/PDF/TSS-pattern.pdf
    PPPS: wikipédia dit autre chose pour intel -> http://en.wikipedia.org/wiki/Thread-local_storage

  19. #19
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    Citation Envoyé par Luc Hermitte
    J'avoue que je serais très curieux de savoir pourquoi s'il existe ce mot clé, ces auteurs (non des moindres) ont choisi la solution bibliothèque. Je ne trouve pas grand chosqe sur google. On dirait que c'est dû au fait que le mot clé ne soit pas présent partout (bien que très répandu à en lire http://www.open-std.org/jtc1/sc22/wg...005/n1815.html)
    Peut-être qu'ils réinventent la roue...

    Citation Envoyé par Luc Hermitte
    Même si tu tiens absolument à réinventer la roue, tu peux regarder comment les autres roues tournent -- et je ne dis pas ça parce que je suis très méfiant (et rarement emballé par) des bibliothèques qui réiventent la roue.
    Je considère en l'occurrence que c'est plutôt Boost qui ici réinvente la roue si les compilos intègrent déjà le TLS et si bien d'autres bibliothèques proposaient auparavant des fonctionnalités semblables. Au plus je n'aurais utilisé que 2 ou 3 autres fonctionnalité de boost...
    De toute façon j'aime pas Boost et tu ne me feras pas changer d'avis sur l'utilisation de bibliothèques: les dépendances sont toujours des nids à problèmes dont je suis ravis de m'être débarrassé depuis longtemps.
    J'ai fais une seule exception: STLport. Mais la raison est surtout historique à cause des trop nombreux bugs dans les implémentations de VC6,VC7,et VC71. Par contre, j'ai pas encore vu de problèmes avec la STL de VC8.

    Citation Envoyé par Luc Hermitte
    PPS: Je vois que Douglas C. Schmidt (Monsieur ACE) a écrit un article 100% orienté bibliothèque sur le sujet -> http://www.cs.wustl.edu/~schmidt/PDF/TSS-pattern.pdf
    L'article date de 1997... ça relativise quelque peu l'intérêt.
    Citation Envoyé par Luc Hermitte
    PPPS: wikipédia dit autre chose pour intel -> http://en.wikipedia.org/wiki/Thread-local_storage
    Ah, tiens, effectivement. j'ai fait l'essai avec ICL et il comprend les 2 syntaxes: celle de GCC et celle de Visual.

    Quoi qu'il en soit mon problème est résolu sans gros effort et sans dépendance à une quelconque bibliothèque, avec une excellente compatibilité sous divers compilos...

    PS: J'ai dis une bétise: finalement ICL ne comprend que la syntaxe de Visual. Peut-être bien que la page de wikipédia consacrée au TLS faisait référence à ICC (sous Linux)

  20. #20
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    Je vais peut être dire une bétise, je suis vraiment pas un guru dans ce domaine ...

    De toute façon il est inconcevable qu'une notion aussi simple que la TLS ne soit pas standardisée à plus ou moins long terme.

    Luc Hermitte désolé d'être en désaccord avec toi, mais la notion de "réinventer la roue" dépend ou tu la place :

    je ne vois que 3 solutions possibles lorsque qu'une techno n'existe pas encore :
    1 - faire soi même une bibliothèque que l'on implémente différemment selon l'archi
    2 - utiliser une librairie exterieure
    3 - attendre l'adoption du standard

    Maintenant rapport à réinventer la roue :

    1 - ok je réinvente la roue à ma sauce à moi, mais quand le standard sera adpoté (il le sera surement) j'aurai gagné un temps énorme

    2 - ok je ne réinvente pas la roue, mais il faut bien voir que si ce n'est pas moi qui la réinvente, c'est les auteurs de la librairie

    3 - ça peut avoir du bon d'attendre que tout soit bien balisé

    Maintenant j'admet que mon jugement peut être biaisé par mes "~déceptions" avec les premières versions de la STL/Port

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 6
    Dernier message: 17/12/2014, 01h37
  2. A propos des variables statiques
    Par gene69 dans le forum Contribuez / Téléchargez Sources et Outils
    Réponses: 1
    Dernier message: 20/08/2011, 19h25
  3. Réponses: 16
    Dernier message: 09/08/2010, 12h14
  4. Utiliser des variables statiques pour des paramètres
    Par el_slapper dans le forum VB.NET
    Réponses: 4
    Dernier message: 11/03/2008, 09h55
  5. Initialiser des variables dans une méthode Statique
    Par ero-sennin dans le forum Langage
    Réponses: 10
    Dernier message: 07/12/2007, 16h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo