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 :

programmation multithread en C++


Sujet :

C++

Vue hybride

deadalnix programmation multithread en... 20/08/2007, 17h48
Invité aie aie aie ma que... 20/08/2007, 18h58
JolyLoic Pour la S(T)L, nulle part,... 20/08/2007, 19h31
Jean-Marc.Bourguet On dit "thread-save". C'est... 20/08/2007, 20h27
nikko34 le mot clé volatile ne peux... 20/08/2007, 20h48
Invité ne disons pas de betises SVP... 20/08/2007, 22h58
Luc Hermitte Je serais fort surpris qu'il... 20/08/2007, 23h42
Invité il y a un impact enorme,... 21/08/2007, 07h45
Mat007 Salut, C'est pas... 20/08/2007, 22h56
Jean-Marc.Bourguet :oops: :mur: 21/08/2007, 07h46
nikko34 je ferais plus un truc du... 21/08/2007, 09h23
Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 537
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 537
    Par défaut programmation multithread en C++
    Bonjour,

    Je m'interesse a la programmation multithread, mais j'ai du mal a trouver de la bonne documentation sur celle-ci.

    Par exemple :
    1/ Ou trouver un information qui me dise si tel ou tel element des bibliotheques Boost ou bien STL sont "thread-resistant".
    2/ Comment dejouer les optimisation faites par le compilos, pour faire des double checks par exemple, pour instancier des singletons.
    3/ est-ce a moi ou au processeur, au systeme ou au processeur de gerer les problemes de coherence de cache ?
    4/ et si c'est a oi, comment faire ? je n'ai trouvé aucun doc la dessus.

    Enfin bref, mon probleme n'est pas le fonctionnement de bibliotheques comme pthread ou son portage C++ dans boost, mais plutot sur le bon usage de celle-ci.

  2. #2
    screetch
    Invité(e)
    Par défaut
    aie aie aie ma que difficile!!

    le multithread on ne trouve pas beaucoup de doc dessus car c'est complique.

    1) Les pages de manuel des fonctions standards peuvent te dire lesquelels sont REENTRANTES ce qui est un terme suffisemment fort pour les rendre thread safe si tout va bien, mais seulement dans certaines conditions.

    Exemple :
    la methode char *strtok(char* string, char* sep);
    cette fonction renvoie le prochain token dans "string" du separateur. Si je dis pas de betise ca s'utilise comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    	char teststr[] = "a b c d e f g h i";
    	char* token = strtok(teststr, " ");
    	do
    	{
    		printf("%s\n", token);
    	}
    	while(token = strtok(0, " "));
    	return 0;
    ce qui se passe ici c'est que la fonction strtok se souvient de la chaine passee en parametre la premiere fois, et elle va partir du principe que les fois d'apres tu veux la suite. Elle stocke donc un etat

    cette fonction est marquee comme non reentrante; si tu l'appelles de deux contextes different, un des deux contextes va imanquablement faire foirer l'autre.

    Il existe une fonction reentrante qui fait la meme chose; cette fonction prend un parametre supplementaire qui est modifie par la fonction et qu'on lui redonne a chaque fois. cela lui evite de bidouiller un truc en interne, et maintenant on peut appeler la fonction de deux contextes differents, le resultat sera probant.

    MAIS meme cette definition compliquee ne peret pas de dire que la fonction est thread safe! elle ne l'est pas (meme reentrante), elle ne fait que fournir des garanties mineures de fonctionnalité.

    Si tu appelles la fonction depuis deux threads differend en lui donnant des donnees differentes, alors le comportement sera correct. En revanche si tu l'appelles avec les memes donnees, alors le resultat est imprevisible; certaines fois ca marchera et d'autres fois les fonctions vont se marcher sur les pieds car ils ecrivent au meme endroit.



    Un autre exemple : la fonction printf est reentrante mais en effectuant printf("plouf\n"); et printf("plop\n"); en meme temps, tu vas aboutir a un affichage etrange
    plooup
    f
    ou un autre truc zarbi car la fonction n'est pas thread safe.

    il est deja difficile d'obtenir la reentrance d'une fonction, alors pour la thread safety c'est quasiment impossible. Au lieu de fournir des versions thread safe, les developpeurs fournissent en general des routines reentrantes (la plupart du temps) mais que le programmeur doit rendre thread safe.

    La reentrance (seule notion que les bibliotheques fournissent en general) est seulement la garantie que la meme fonction appliquee sur deux donnees DIFFERENTES peut etre realisee en parallele.



    Pour en revenir a la thread safety, pour la fonction (deja reentrante) strtok_r, il faudrait pouvoir "locker" la chaine que l'on modifie. Si strtok_r veut y acceder il doit la reserver. Ainsi si deux strtok_r veulent bidouiller "a b c d e f g h i" alors un des deux doit attendre que l'autre aie fini.

    Je ne sais pas si je me fais bien comprendre, mais pour resumer : la fonction strtok n'est pas reentrante et il ne faut jamais l'utiliser en contexte multithread.
    la fonction strtok_r est reentrante mais l'appliquer dans deux threads separes sur la meme donnee va donner un resultat erroné

    Il existe des bibliotheques fournissant des composants thread-safe (exemple : Qt). Cela est precise dans la doc. Les composants STL et boost ne sont jamais thread safe!






    2) Je ne sais pas ce que tu essayes de faire, je suppute le genre de code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Singleton* Singleton::get()
    {
        if(! instance)
        {
            LOCK;
            if(! instance)
            {
                instance = new Singleton();
            }
            UNLOCK
        }
        return instance;
    }

    ce code a deja ete vu des dizaines de millions de fois, et il n'est PAS THREAD SAFE!! en debug sans optis, comme en release. (Ca doit etre ca qu'on appelle le double check non?)
    des tas de gens se sont arraches les cheveux et tous ont aboutis a une seule conclusion : la seule facon de faire un Singleton thread safe c'est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Singleton* Singleton::get()
    {
        LOCK;
        if(! instance)
        {
            instance = new Singleton();
        }
        UNLOCK
        return instance;
    }

    et crois moi des gens tres intelligents ont essaye mieux

    3) et 4) pour le cache c'est un autre truc de ouf!
    il faut que tu declares tes donnees partagees volatile.
    Cela signifie que le compilateur ne mettra pas le resultat dans un registre, il ira verifier la memoire. Toute donnees accedee par deux threads doit etre declaree volatile. Verifie le mot cle volatile pour plus d'info.

    Et meme la ca suffit pas! Dans le cas special ou tu essayes de te servir de la memoire pour synchroniser des threads c'est mal barré aussi :-/

    exemple tres simple :
    Thread 1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    extern volatile int data;
    extern volatile bool ready;
     
    void send()
    {
        data = 12;
        ready = true;
    }
    Thread 2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    extern volatile int data;
    extern volatile bool ready;
     
    void receive()
    {
        while(! ready) /*wait*/;
        /* la donnee est prete */
        use(data);
    }

    malheureusement ce cas la n'est pas thread safe non plus (puree c'est casse pieds le multi threading)

    la raison c'est que rien ne force le controleur memoire a tout ecrire dans l'ordre; celui ci place les requetes en queue et les ecrit quand bon lu isemble, comme ca lui plait.
    Il peut donc decider d'ecrire "ready" avant "data", et la PAF ton thread 2 verifie ready, youhouh ca marche, tu lis data et... c'est pas (encore) la bonne valeur. Le controleur memoire a decide de ne pas encore ecrire data. Et si ca lui chante tu ne peux rien y faire.

    Il existe pour contrer ce probleme un mecanisme appele "memory barrier" (a lire sur wikipedia) qui force l'ordonnancement des stockages ou des lectures.

    Dans le cas plus haut il faudrait placer une "write barrier" : cela signifie que l'ordonnancement devient important : avec la write barrier tu demande a ce que TOUT CE QUI SE TROUVE AVANT la barriere soit effectivement ecrit AVANT TOUT CE QU'IL Y A APRES

    exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void send()
    {
        data = 12;
        WRITE_BARRIER;
        // je veux que tous les trucs avant la barrier (soit data) soit ecrits avant ce qui suit (soit ready)
        ready = true;
    }








    Comme tu peux le voir rien qu'en 4 questions on a balaye la reentrance, le bug du singleton (a propos si tu vois pas pourquoi ce n'est pas thread safe je peux l'expliquer; mais si tu ne le vois pas j'ai peur que tu loupes des problemes de thread safety du meme niveau, ca fait donc un bon exercice) et les memory barrier pour le controleur memoire.

    Je ne pense pas que tu avais entrevu 10% de ces problemes, c'est pour ca que la doc sur les threads est dure a trouver : il est deja difficile de connaitre les problemes de multithreading, c'est donc dur de trouver les solutions.

    Bon mal de crane cher codeur ^^

  3. #3
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par deadalnix Voir le message
    1/ Ou trouver un information qui me dise si tel ou tel element des bibliotheques Boost ou bien STL sont "thread-resistant".
    Pour la S(T)L, nulle part, comme rien n'est spécifié dans le standard, qui ignore actuellement la notion de multithread, chaque implémentation est libre de faire ce qu'elle veut. Par exemple, l'implémentation que j'utilise en général document ça http://msdn.microsoft.com/library/de...rdCLibrary.asp

    En absence de doc, si on se sent en veine, et si on ne fait pas un système mettant en danger la vie des gens, on peut supposer en général un mode "sans surprises", c'est à dire que si on accède à chaque objet que dans un seul thread à la fois, il n'y a pas de données partagées non documentées qui peuvent faire tout foirer.

    Citation Envoyé par deadalnix Voir le message
    2/ Comment dejouer les optimisation faites par le compilos, pour faire des double checks par exemple, pour instancier des singletons.
    Normalement, tu utilises des primitives spécifique à du multithread (locks, compare&swap...), et dans ce cas un compilo intelligent les connait, et sait qu'il ne doit pas bouger le code autour, et un compilo bête ne les connait pas, et comme pour toute fonction inconnue sait qu'il ne doit pas bouger le code autour. Donc ça marche bien.
    Si tu n'utilises aucune de ces primitives, je ne sais pas trop ce que tu espères atteindre comme sécurité multithread, mais j'ai bien peur que ça ne marche pas, même sans réorganisation du code par le compilo (en particulier, si le double-check est bien ce à quoi je pense, ça ne fonctionne pas...).
    Citation Envoyé par deadalnix Voir le message
    3/ est-ce a moi ou au processeur, au systeme ou au processeur de gerer les problemes de coherence de cache ?
    Je ne sais pas à qui c'est, mais ce n'est pas à toi en tout cas.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  4. #4
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par deadalnix Voir le message
    1/ Ou trouver un information qui me dise si tel ou tel element des bibliotheques Boost ou bien STL sont "thread-resistant".
    On dit "thread-save". C'est dans la doc de chaque bibliothèque. Si c'est pas documenté, considère que ce ne l'est pas. Et n'oublie pas qu'il y a plusieurs sorte de thread savety.

    2/ Comment dejouer les optimisation faites par le compilos, pour faire des double checks par exemple, pour instancier des singletons.
    Ne cherches pas à déjouer cela, les processeurs font les mêmes... Le problème dans le cas du double check est un problème de cohérence de cache, donc:
    3/ est-ce a moi ou au processeur, au systeme ou au processeur de gerer les problemes de coherence de cache ?
    La responsabilité est à plusieurs niveaux: les processeurs offrent certaines garanties.

    Les systèmes batits au dessus s'en servent pour en fournir d'autres -- parfois en ne permettant pas ce que le processeur autorise pourtant, parfois en donnant des garanties plus fortes.

    Les OS en fournissent encore d'autres -- en général ils se contentent de choisir un de ceux possibles pour le système et configurent le système de manière adéquate.

    Et de toute manière ton code doit utiliser les primitives du processeur ou du systèmes pour en profiter.

    Ne pas oublier que ce n'est pas parce que la version courante n'utilise pas une liberté que ce ne sera pas le cas dans le futur.

    Résumé: utilise les primitives de synchro de l'OS ou des bibliothèques baties par des spécialistes. Hors de cela, peu de salut... tu peux devenir spécialiste, mais il faut des capacités d'investigations supérieures aux tiennes si

    4/ et si c'est a oi, comment faire ? je n'ai trouvé aucun doc la dessus.
    La doc des processeurs est en général assez complète. Si j'ai bonne mémoire, celle du Sparc est presque un tutorial en la matière.

    Les documents de POSIX (j'ai pas l'URL sous la main, ils sont disponibles gratuitement à l'opengroup) et de Windows (Herb Sutter les a communiqué au comité C++, "ISO C++" et tu as de la chance auprès de google) décrivent ce qui est garanti par ces OS. Dans les documents du comité, tu vas trouver aussi des propositions de ce qui sera exigé par la future norme C++.

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    le mot clé volatile ne peux pas être utilisé sur les objets de la SL C++ ( Screech parle beaucoup de C en fait mais moins de C++ ).

    La SL ne connait pas les threads mais normalement dans son implémentation comme le dit JolyLoic il n'y a pas de "surprises": pas de fonctions du style de strtok en C.

    J'ai trouvé boost.thread bien sympa à utiliser avec son ensemble de lock/mutex/condition etc.. Je n'ai jamais eu de problème pour l'instant avec les objets de la SL ou boost.

  6. #6
    screetch
    Invité(e)
    Par défaut
    ne disons pas de betises SVP ^^

    je ne parle pas de la STL car cela pose plus de probleme de parler de volatile std::vector<int> que de volatile bool


    pourtant les memes problemes existent, avec le defaut d'etre difficilement solubles

    voici un exemple de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #include <vector>
    #include <windows.h>
     
     
    int thread1fun(std::vector<int>* vec)
    {
        vec->push_back(0);
        printf("initial value : %d\n", vec->at(0));
        vec->pop_back();
        while(vec->empty()) /*wait*/;
        printf("received an element : %d\n", vec->at(0));
        return 0;
    }
     
    int thread2fun(std::vector<int>* vec)
    {
        Sleep(1000);
        printf("pushing an element\n");
        vec->push_back(1);
        return 0;
    }
     
     
    int main(int argc, char *argv[])
    {
        std::vector<int> s_ListOfInt;
        HANDLE thread1 = CreateThread( 0, 12000, (LPTHREAD_START_ROUTINE)thread1fun, &s_ListOfInt, 0, 0);
        if(!thread1)
            return 1;
        HANDLE thread2 = CreateThread( 0, 12000, (LPTHREAD_START_ROUTINE)thread2fun, &s_ListOfInt, 0, 0);
        if(! thread2)
            return 1;
        WaitForSingleObject(thread1,2000);
        WaitForSingleObject(thread2,2000);
        return 0;
    }
    ici, sous Visual il n'y a pas de probleme. Compilé avec GCC en release, ce code va provoquer une boucle infinie car le vecteur va travailler entierement sur des registres et donc il ne verra pas la difference apportee a la memoire par l'autre thread.

    Il est impossible de declarer std:.vector<> volatile car alors seules les methodes volatiles pourraient etre appelees (et elles sont pas legion : il y en a pas)

    la solution : ben y'en a pas dans la STL.

    voici un code avec une classe MiniVector qui corrige le probleme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    #include <windows.h>
    #include <cstdio>
     
    template< typename T >
    class MiniVector
    {
    private:
        size_t m_size;
        T       m_value[12];
    public:
        MiniVector() :
            m_size(0),
            m_value()
        {
        }
     
        void push_back(const T& value)
        {
            m_value[m_size++] = value;
        }
     
        void pop_back()
        {
            m_size--;
        }
     
        const T& at(size_t index) const
        {
            return m_value[index];
        }
     
        bool empty() const
        {
            return m_size == 0;
        }
     
        void push_back(const T& value) volatile
        {
            m_value[m_size++] = value;
        }
     
        void pop_back() volatile
        {
            m_size--;
        }
     
        const volatile T& at(size_t index) const volatile
        {
            return m_value[index];
        }
     
        bool empty() const volatile
        {
            return m_size == 0;
        }
    };
     
     
    int thread1fun(volatile MiniVector<int>* vec)
    {
        vec->push_back(0);
        printf("initial value : %d\n", vec->at(0));
        vec->pop_back();
        while(vec->empty()) /*wait*/;
        printf("received an element : %d\n", vec->at(0));
        return 0;
    }
     
    int thread2fun(MiniVector<int>* vec)
    {
        Sleep(1000);
        printf("pushing an element\n");
        vec->push_back(1);
        return 0;
    }
     
     
    int main(int argc, char *argv[])
    {
        MiniVector<int> s_ListOfInt;
        HANDLE thread1 = CreateThread( 0, 12000, (LPTHREAD_START_ROUTINE)thread1fun, &s_ListOfInt, 0, 0);
        if(!thread1)
            return 1;
        HANDLE thread2 = CreateThread( 0, 12000, (LPTHREAD_START_ROUTINE)thread2fun, &s_ListOfInt, 0, 0);
        if(! thread2)
            return 1;
        WaitForSingleObject(thread1,2000);
        WaitForSingleObject(thread2,2000);
        return 0;
    }
    ici, on voit que l'on a du dupliquer toutes les methodes pour mettre le mot cle volatile. Aie . Ensuite, on peut declarer un MiniVector<T> volatile et appeler les methodes quand meme (ce que la STL ne permet pas). Le compilateur choisira la meilleure fonction entre la volatile et la pas volatile, selon le type d'entree (vector volatile ou pas)


    A noter que les versions non volatile des methodes sont superflues car cela fonctionne tres bien sans; mais il y a peu de chance que vous souhaitiez appeler uniquement des methodes volatiles ce qui force une baisse des performances, du coup avoir un overload volatile ou non-volatile permet d'obtenir le meilleur des mondes.
    On attend evidemment une version du C++ qui permette de ne pas copier coller les methodes pour rendre la classe compatible volatile.




    Comme quoi les memes problemes en C++ existent toujours, ils ont juste ete encapsules mais je trouvais ca plus clair de ne pas les mentionner

  7. #7
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    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 296
    Par défaut
    Je serais fort surpris qu'il y ait un impact de perf sur les fonctions volatiles. volatile sur les objets agit comme const : un marqueur.
    C'est d'ailleurs un moyen pour définir du code résistant aux races conditions ; cf l'article d'Andrei Alexandrescu à ce sujet.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  8. #8
    screetch
    Invité(e)
    Par défaut
    il y a un impact enorme, celui de mettre THIS en volatile comme les methodes const passent THIS en const. Si toute tes methodes sont olatiles alors a chaque fois que tu accedes a un champ de la classe tu dois aller le lire en memoire.

  9. #9
    Membre Expert

    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
    Par défaut
    Salut,

    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    On dit "thread-save". (...) Et n'oublie pas qu'il y a plusieurs sorte de thread savety.
    C'est pas plutôt thread-safe et thread-safety ?

    MAT.

  10. #10
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Mat007 Voir le message
    Salut,



    C'est pas plutôt thread-safe et thread-safety ?

    MAT.

  11. #11
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    je ferais plus un truc du style en utilisant un vector normal plutôt que redéfinir un nouveau vector, enfin ça dépend du contexte

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
           boost::mutex::scoped_lock lock( vectorEmptyMutex );
     
            while( vector.empty() )
            {       
                vectorEmptyCondition.wait( lock );
            }
    avec vectorEmptyCondition étant un boost::condition

  12. #12
    screetch
    Invité(e)
    Par défaut
    Ca ne resout pas le probleme volatile.

    Le fait de locker et le fait de rester dans le registre sont deux problemes different.

    Ici tu peux avoir une boucle infinie quand meme car la fonction empty est inline et travaille sur le registre, lequel ne change jamais (puisque seule la memoire change). L'ajout de volatile forcera le compilateur a generer du code qui va relire la memoire et pas le registre, et cela fonctionnera.

    Les mutex ne resoudront jamais ce probleme.

Discussions similaires

  1. Qt et la programmation multithread
    Par yan dans le forum Multithreading
    Réponses: 1
    Dernier message: 06/10/2011, 23h58
  2. question sur un programme multithread
    Par blueLight dans le forum Windows
    Réponses: 10
    Dernier message: 17/07/2008, 09h23
  3. Programmation multithread pour débutant
    Par oodini dans le forum C++
    Réponses: 5
    Dernier message: 07/03/2008, 14h14
  4. temps d'execution d'un programme multithread
    Par La taupe dans le forum C
    Réponses: 2
    Dernier message: 10/01/2007, 17h44
  5. Programmation multithreads ?
    Par rulianf dans le forum C++
    Réponses: 2
    Dernier message: 03/02/2006, 20h17

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