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 :

pthread et mutex


Sujet :

C++

  1. #1
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 55
    Points : 54
    Points
    54
    Par défaut pthread et mutex
    bonjour

    j'ai un petit souci avec mon mutex pthread qui se comporte pas comme j'aimerais

    il me semblait que d'une certaine maniere pthread faisait une queue FIFO de tous les thread qui faisaient lock() sur un mutex deja locke, et qu'il les reveillait dans l'ordre dans lequels ils sont appelle lock(), et apparement c'est pas forcement le cas. Sur 2 machines j'ai 2 comportement different, ce qui me pose probleme c'est que sur l'une :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    while (true) {
       mutex.lock();
       ...
       mutex.unlock();
    }
    ne rend jamais la main a d'autres threads qui auraient appelle mutex.lock()


    aurais-je mal initialise mon mutex ?
    je l'initialise commee suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    pthread_mutex_t* lMutex = new pthread_mutex_t;
    if(::pthread_mutex_init(lMutex, 0))
       throw Exception(eOtherError, "Mutex::Mutex() can't create!");

  2. #2
    Membre averti Avatar de Higestromm
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    516
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 516
    Points : 412
    Points
    412
    Par défaut
    je ne suis pas sur mais je crois que tu confond mutex et sémaphore...
    Pour recuperer un mutex c'est un peu du hazard
    Pour recuperer un sémaphore il y a un sisteme de liste

    Donc ton comportement ne me parais pas plus étrange que ca vu que ta boucle ne fait rien d'autre... mais bon ... je peux me tromper
    J'aime pas les épinards... Mais alors pas du tout

  3. #3
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 55
    Points : 54
    Points
    54
    Par défaut
    Citation Envoyé par Higestromm
    Pour recuperer un mutex c'est un peu du hazard
    sans dec

    Citation Envoyé par Higestromm
    Pour recuperer un sémaphore il y a un sisteme de liste
    un semaphore initialise a 1 donc... j'ai essaye et j'ai malheureusement un resultat similaire, faut que je regarde dans l'implementation de ma semaphore

    Citation Envoyé par Higestromm
    Donc ton comportement ne me parais pas plus étrange que ca vu que ta boucle ne fait rien d'autre... mais bon ... je peux me tromper
    je sais pas si c'est etrange, mais je dit que c'est du delire, car imagine une autre fonction similaire apellee dans un autre thread... serait en permanence bloquee

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Points : 473
    Points
    473
    Par défaut
    Il n'y a aucune gestion de liste d'accès avec un mutex. Une fois le verrou libéré, les threads sont remis en concurrence pour l'accès au verrou. L'allocation dépend de l'ordonnanceur natif de l'OS.
    Le code que tu montres peut donc amener une situation de famine.
    Les mutex sont utiliser pour garantir l'accès à une ressource en situation d'exclusion mutuelle.

    Pour synchroniser un ensemble de tâches, il faut utiliser d'autre type de primitive de synchronisation comme les semaphores, ou les 'variables conditions'

  5. #5
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2002
    Messages : 290
    Points : 325
    Points
    325
    Par défaut
    déjà avec un sleep(0) derriere le unlock() cela devrait mieux marcher...

    Mais effectivement il n'y a aucune gestion de liste pour l'acces à un mutex...

    le sleep(0) permet de redonner la main a un autre thread/process au niveau de l'ordonnacement...

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Points : 473
    Points
    473
    Par défaut
    La synchronisation de tâche, c'est en général quelquechose qui se plannifie. Il est impossible de se baser sur de la bidouille. Peut-être qu'avec un sleep(), un printf, ou je ne sais quoi ça peut ponctuellement empêcher la famine, mais cela ne résoud rien.
    Le même code avec un compilo différent, ou une plate-forme différente ou une charge sur la machine différente produira le même genre de problème.
    De plus, la solution ici est simple. Utiliser un sémaphore.

  7. #7
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 55
    Points : 54
    Points
    54
    Par défaut
    Citation Envoyé par VoidSeer
    Utiliser un sémaphore.
    ah mais je te crois sur parole 8)
    je pensais qu'un mutex et qu'une semaphore de 1 etait la meme chose, voila je me coucherais moins bete ce soir

    probleme : mon implementation n'est apparement pas plateforme-independante car meme avec une semaphore de 1 le probleme persiste, ca delire profond et je vais changer d'implementation (et merdeuuuu). peut etre une bonne raison de passer a quelque chose de plus serieux. vous me conseillez quoi, boost ?

    merci pour le sleep(0), ya de l'idee mais bon

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Points : 473
    Points
    473
    Par défaut
    Normalement avec les pthread sont compatible avec toute les plate-formes Unix. Je trouve le problème étrange...
    Dans l'absolu, l'utilisation d'une bibliothèque de synchro risque de ne pas changer grand-chose, vu que beaucoup encapsulent les pthreads.
    On peut en voir un peu plus (pas trop hein...) du code ? Y'a peut-être un problème tout pipi ?
    Ou mieux, avoir une idée du pb à résoude ?

  9. #9
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 55
    Points : 54
    Points
    54
    Par défaut
    j'utilise les classes dispo ici : http://manitou.gel.ulaval.ca/~parizeau/PACC/
    je sais que c'est pas standard mais c'est simple et puis c'est pas une usine a gaz. Ca encapsule les pthread

    si je decommente le sleep(0.01) ca marche comme espere mais... sinon le thread2 n'a jamais acces
    j'ai un peu trace le probleme dans le code de semaphore, lorsque la condition fait signal l'autre ne se reveille pas tout de suite (pourquoi ?) et le temps qu'elle se reveille, le thread 1 est deja retourne dans le code

    en attendant mieux je vais mettre ce sleep(0.01) dans le code de post()... pas que ca a faire moi

    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
     
    PACC::Threading::Semaphore semaphore(1);
     
    class Test : public PACC::Threading::Thread {
      char c;
      int w, w2;
    public:
      Test(char c_, int w_, int w2_) : c(c_), w(w_), w2(w2_) {}
    protected:
      void main() {
        sleep(w);
        while (true) {
          cout << c << " wait" << endl;
          semaphore.wait();
          cout << c << " got access" << endl;
          sleep(w2);
          cout << c << " post" << endl;
          semaphore.post();
          sleep(0.01);
        }
      }
    };
     
     
     
    int main(int argc, char *argv[])
    {
      Test t1('1', 0, 2);
      Test t2('2', 1, 2);
     
      t1.run(); t2.run();
      t1.wait(); t2.wait();
    }

  10. #10
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    boost::thread m'avais l'air pas mal, pas tellement dans la façon somme toute classique dont il traite la concurrence, mais surtout dans la façon dont il est exception safe.
    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.

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Points : 473
    Points
    473
    Par défaut
    Ce que tu as, c'est un vrai pb de synchronisation. Avec ton code, la tâche 1 peut boucler à l'infini

    Une solution classique à ce problème est d'utiliser 2 sémaphores de synchonisation (initialisés à 0)
    Soit sem1, sem2 rattachés respectivement à la tâche 1 et tâche 2.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
        Tâche 1                                 Tâche 2
     
      sem1.wait()                    
            |                                    sem1.post()
            |  (section critique)        sem2.wait()
            |
      sem2.post()

  12. #12
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 55
    Points : 54
    Points
    54
    Par défaut
    alors désolé là je ne te suis pas du tout... dans ton exemple la tâche 2 va "autoriser" la tâche 1 a fonctionner en section critique, et inversement

    mais je n'ai jamais dit que la fonction de la tâche 2 ALLAIT être appellée, j'ai dit qu'elle POUVAIT l'être (ou pas) et dans ton cas la tâche 1 attendrait, ca va pas

    en pratique j'ai plus de 2 fonction (une qui tourne en boucle et d'autres normales type mutex)... et si aucune n'est "en attente" je veux qu'elle continue à tourner en boucle

    tu ne semble pas valider mon idée de semaphore de 1 (ci dessous)... pourquoi ? problème identique à mutex ?



    ====>>> est ce que tu comprend mon idée de "queue" de processus en attente ??? est-ce demander la lune ???!!!! je suis parfaitement OK avec ton semaphore de 0 mais il ne répond pas à mon problème particulier


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    sem = semaphore(1)
    tâche 1 : boucle {sem.wait(); ... ; sem.post();} fin de boucle
    tâche 2 : boucle {sem.wait(); ... ; sem.post();} fin de boucle

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Points : 473
    Points
    473
    Par défaut
    Effectivement la solution que avec 2 semaphore permet de faire fonctionner alternativement 2 tâche. Cela ne répond pas directement à ton problème.

    Le pb avec ton code c'est qu'il se peut que ta tâche 2 ne soit jamais élue. A la réflexion, je ne suis pas très sûr qu'il y est un méchanisme de liste d'attente ordonnée sur les sémaphores de la norme posix. Si je me rappelle bien, ils sont basé sur les 'condition variables', y'a donc de grande chance qu'une fois le jeton libéré, il y est encore un pb de concurrence.

    J'ai une solution un peu ad hoc, que je n'ai pas le temps de tester, ni même de vraiment regarder de près, alors, ne tirez pas sur le pianiste.

    L'idée est de vérifier à chaque itération de la tâche principale, si aucune tâche n'est en attente. Si c'est le cas, il faut les synchroniser puisque la tâche 2 doit être la seule à s'executer. La méthode doit pouvoir se généraliser facilement à N tâches.

    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
     
    sem_1 : sémaphore de synchro de la tâche principale
    sem_2 : sémaphore de la tâche ponctuelle 
    mutex : garde d'accès aux données partagée entre les 2 tâches
    is_waiting : booléen valant vrai si la tâche 2 cherche à intervenir (initialisé à 0)
     
    Tâche principale     
    ------------------
    loop                        
      mutex.lock()   
      if (is_waiting)
        mutex_unlock             
        sem2.post()  /* Active la tâche en attente */
        sem1.wait()  /* Se met en attente de la fin de T2 */
     
      else
        mutex.unlock()
      fi
        /* Vit sa vie */
      end loop
     
     
    Tâche 2
    ---------
      mutex.lock()
      is_waiting = true
      mutex.unlock()
     
      sem2.wait()  /* Attend la fin d'execution de l'itération de T1 */
     
      /* Vis sa vie en exclusion avec T1 */
     
      // Clean
      mutex.lock()
      is_waiting = false
      mutex.unlock()		
     
      sem1.post() /* Réveille T1
      die.
    On peut généraliser ceci à N tâche, en utilisant, en plus du booléen, un vecteur dans lequel on empile les références sur les sémaphores privés des N tâches en attente, que l'on libère 1 par 1.

    Une fois encore, c'est un code pondu en 5 min, donc à prendre avec des pincettes.

  14. #14
    Membre averti Avatar de Higestromm
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    516
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 516
    Points : 412
    Points
    412
    Par défaut
    Un peu hors sujet mais ca m'interesse beaucoup.

    Est ce qu'il existe un equivalent des sections critiques windows en standard dans le c++ ou bien fonctionnant sous linux ?
    J'aime pas les épinards... Mais alors pas du tout

  15. #15
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 55
    Points : 54
    Points
    54
    Par défaut
    merci pour ton algo je regarderais ca

    j'ai compris le probleme (c'est déja bien) de mon algo d'au dessus... je reflechis à une solution generique style queue fifo de semaphores et je te/vous tient au jus

  16. #16
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 55
    Points : 54
    Points
    54
    Par défaut
    en standard dans le c++
    ya rien en standard, c'est OS/lib dépendant. Mais les pthread sont portables

    sur Windows ya aussi l'api Win32 gère ca - mais pour moi Win32 c'est un charabiat de langue morte -

  17. #17
    Membre habitué
    Profil pro
    Enculeur de mouches
    Inscrit en
    Septembre 2003
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : Enculeur de mouches

    Informations forums :
    Inscription : Septembre 2003
    Messages : 133
    Points : 161
    Points
    161
    Par défaut
    Ha bon, POSIX n'est pas un standard ?

    Le soucis (que tu semble avoir compris) est que la prabalité que le scheduler passe la main à un autre thread entre la fin et le début du while() (le unlock est suit suivit par un JUMP, un test et un lock, puis la section critrique, puis re*, etc...) est vraiment très faible. Suffisemment, visiblement pour que ça n'arrive jamais dans un test "grandeur nature"...

    D'où l'idée du sleep() qui force à passer la main, ne parraît pas du tout une bonne idée.

    En ce qui concerne la FIFO des thread, c'est vrai à condition d'utiliser cette politique. Pour info elle implémente FFP (Fixed Priority Premptive), contrairement à Round-Robin (et c'est uniquement dans ce cas qu'il est approprié de parler de "jeton"... Bon j'ai quand même compris le post qui utilise ce terme, and that's the point). Si tout test thread ont la même priorité, ceci dis, ça revient au même...

    C'est pas parceque les threads sont organisé en FIFO (dans l'ordonanceur) qu'il chope le mutex en FIFO. Donc ce qu'il faut c'est après le unlock() c'est un genre de "yield()", c'est à dire une fonction qui dis à l'ordonnanceur de passer la main à un autre thread, qui verouillera le mutex, etc...

    Au pire tu peux toujours implémenter une liste d'abonnement qui implémentera la FIFO sur le mutex... La tu sera sûr du comportement... 8)
    Gaïa n'est pas une marchandise.

  18. #18
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 55
    Points : 54
    Points
    54
    Par défaut
    ok j'ai pondu quelque chose (je précise que j'ai taillé ca a la serpe et au burrin)

    implementation :

    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
     
    class FifoMutex {
        Mutex mutex;
        deque<Semaphore *> freeSem;
        deque<Semaphore *> waitingSem;
        Semaphore * computingSem;
     
    	void init(int i) {
    	    computingSem = NULL;
    		for (int j=0; j<i; j++) freeSem.push_back(new Semaphore(0));
    	}
     
    public:
    	FifoMutex() {init(32);}
     	FifoMutex(int i) {init(i);}
     
    	void lock() {
    	    mutex.lock();
    		Semaphore * sem;
    		if (freeSem.empty())
      			sem = new Semaphore(0);
    		else {
      			sem = freeSem.front();
      			freeSem.pop_front();
    		}
    		if (computingSem == NULL)
    			computingSem = sem;
    		else {
    			waitingSem.push_back(sem);
    	   	    mutex.unlock();
    			sem->wait();
    			return;
    		}		
       	    mutex.unlock();
    	}
     
    	void unlock() {
    	    mutex.lock();
    		if (waitingSem.empty())
    			computingSem = NULL;
    		else {
    		    computingSem = waitingSem.front();
    		    waitingSem.pop_front();
    		    computingSem->post();
    		}    
       	    mutex.unlock();
    	}
    };

    test :

    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
     
    Mutex mutex;
    FifoMutex fifoMutex;
     
    class MutexTest : public PACC::Threading::Thread {
      int c;
      float w, w2;
    public:
      MutexTest(int c_, float w_, float w2_) : c(c_), w(w_), w2(w2_) {}
    protected:
      void main() {
        sleep(w);
        mutex.lock();
        cout << c << " got access" << endl;
        sleep(w2);
        mutex.unlock();
      }
    };
     
    class FifoMutexTest : public PACC::Threading::Thread {
      int c;
      float w, w2;
    public:
      FifoMutexTest(int c_, float w_, float w2_) : c(c_), w(w_), w2(w2_) {}
    protected:
      void main() {
        sleep(w);
        fifoMutex.lock();
        cout << c << " got access" << endl;
        sleep(w2);
        fifoMutex.unlock();
      }
    };
     
     
     
    int main(int argc, char *argv[])
    {
      int nb = 10;
      float sleep = 0.4;
      MutexTest* mutextest[nb];
      FifoMutexTest* fifotest[nb];  
     
      cout << "according to fifo rule, should be 0 -> 10" << endl;
      cout << "---------- MUTEX TEST ---------" << endl;
      for (int i=0; i<nb; i++) {
       	mutextest[i] = new MutexTest(i, i * 0.02, sleep);
       	mutextest[i]->run();
      }
      for (int i=0; i<nb; i++) {
    	mutextest[i]->wait();
    	delete mutextest[i];
      }
     
      cout << "---------- FIFO-MUTEX TEST ---------" << endl;  
      for (int i=0; i<nb; i++) {
       	fifotest[i] = new FifoMutexTest(i, i * 0.02, sleep);
       	fifotest[i]->run();
      }
      for (int i=0; i<nb; i++) {
    	fifotest[i]->wait();
    	delete fifotest[i];
      }
     
    	system("pause");
    }
    resultat sur ma machine qui posait 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
     
    according to fifo rule, should be 0 -> 10
    ---------- MUTEX TEST ---------
    0 got access
    9 got access
    8 got access
    7 got access
    6 got access
    5 got access
    4 got access
    3 got access
    2 got access
    1 got access
    ---------- FIFO-MUTEX TEST ---------
    0 got access
    1 got access
    2 got access
    3 got access
    4 got access
    5 got access
    6 got access
    7 got access
    8 got access
    9 got access
    ya du mieux

  19. #19
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Points : 473
    Points
    473
    Par défaut
    Arf, c'est qu'à tous on est p't'être pas si mauvais.

    Allez, classe l'affaire va !

  20. #20
    Membre habitué
    Profil pro
    Enculeur de mouches
    Inscrit en
    Septembre 2003
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : Enculeur de mouches

    Informations forums :
    Inscription : Septembre 2003
    Messages : 133
    Points : 161
    Points
    161
    Par défaut
    Bon la flemme de lire tout ça à 5 heure moins 10... Honte à moi

    Mais j'aime bien :
    Citation Envoyé par Nico65
    ok j'ai pondu quelque chose (je précise que j'ai taillé ca a la serpe et au burrin)
    Un de mes amis celtique ?

    Ferais-tu parti des "amis de Merlin", ceux qui se réunissent périodiquement dans [ce qui reste de] Brocéliande ? UN BRETON QUOI !!?

    Aller, Breizh A Tao, c'est pas a toi, mais TOUS que je le dis ! Vive Engann !!!

    (Je délire, bretonnant mais pas cinglé je suis...)
    Gaïa n'est pas une marchandise.

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

Discussions similaires

  1. Pthreads: Conditions et Mutex
    Par Arkenis dans le forum Débuter
    Réponses: 19
    Dernier message: 28/01/2015, 19h05
  2. Pthread et semaphores
    Par Yabo dans le forum Linux
    Réponses: 9
    Dernier message: 30/03/2008, 00h09
  3. pthread et mutex
    Par yamissa dans le forum C++
    Réponses: 6
    Dernier message: 23/11/2007, 00h02
  4. pthread, mutex
    Par ELKCHAOU dans le forum MFC
    Réponses: 5
    Dernier message: 14/07/2005, 20h46
  5. Réponses: 4
    Dernier message: 27/08/2003, 21h34

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