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 : pthread_join


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Décembre 2003
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 99
    Par défaut Pthread : pthread_join
    Bonjour,

    J'ai un programme qui lance des threads au "compte goutte".
    J'aimerais avant la fin du programme attendre qu'ils se terminent tous en utilisant pthread_join, mais je ne trouve pas de solution convenable.

    Si je fais une boucle de ce style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        for (i = 0; i < MAX_THREAD; i++)
        {    
            pthread_join (threads [i], NULL);	    
        }
    Bah ça marche pas, car MAX_THREAD n'est pas forcément atteint à la fin du programme, pthread_join sort alors un seg fault si threads[i] n'a jamais été créé (ce qui est normal).

    Si j'utilise un compteur pour mes threads (protégé par un mutex) en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        for (i = 0; i < nbCurrentThread; i++)
        {    
            pthread_join (threads [i], NULL);	    
        }
    Bah ca marche pas non plus, car à un instant t je peux avoir nbCurrentThread mais l'instant suivant plus que nbCurrentThread - 1 et donc le thread nbCurrentThread ne sera pas attendu.

    Pour palier à ça , je peux mettre un mutex sur la boucle d'attente, mais je risque les dead lock ou d'être dans un traitement séquentiel, ce qui ne m'intéresse pas.

    Je ne sais pas si c'est très clair ce que je dis ? Si oui, avez-vous une piste à me proposer ?

    Merci d'avance.

  2. #2
    Membre confirmé
    Inscrit en
    Décembre 2003
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 99
    Par défaut
    C'est tout bête en fait, il suffit de rajouter une condition :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    for (i = 0; i < MAX_THREAD; i++)
    {    
        if (threads[i] != NULL)
            pthread_join (threads [i], NULL);	    
    }

  3. #3
    Membre très actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2009
    Messages
    172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2009
    Messages : 172
    Par défaut
    Salut,

    Je suis loin d'être un expert en C mais ta solution me titille un peu niveau algo.

    Imagine que le thread "i = 5" se termine avant le thread "i=7". Ta boucle ne s'arretera-t-elle pas avant d'avant fait son boulot ou j'ai mal compris?

    En fait ce qui m'embrouille c'est pourquoi tu dis qu'à un moment tu peux avoir nbThreads - 1. Théoriquement un thread qui se termine attend qu'on récupère sa valeur de retour non? (à moins que tu l'aies configurer autrement). Donc si tu n'as pas changé l'attribut par défaut PTHREAD_CREATE_JOINABLE en PTHREAD_CREATE_DETACHED il attendra tranquillement que ta procédure principale le rejoigne.

    Je pense que tu t'es pris la tête pour rien sur ce coup là!

  4. #4
    Membre confirmé
    Inscrit en
    Décembre 2003
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 99
    Par défaut
    Bonjour,

    Imagine que le thread "i = 5" se termine avant le thread "i=7". Ta boucle ne s'arretera-t-elle pas avant d'avant fait son boulot ou j'ai mal compris?
    En fait je vais jusqu'à MAX_THREAD, donc la boucle aura attendu la fin de tous les threads, à moins que je passe à coté de qqchose ?

    En fait ce qui m'embrouille c'est pourquoi tu dis qu'à un moment tu peux avoir nbThreads - 1. Théoriquement un thread qui se termine attend qu'on récupère sa valeur de retour non? (à moins que tu l'aies configurer autrement). Donc si tu n'as pas changé l'attribut par défaut PTHREAD_CREATE_JOINABLE en PTHREAD_CREATE_DETACHED il attendra tranquillement que ta procédure principale le rejoigne.
    En fait c'est le cas suivant qui me prend la tête :

    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
    MAX_THREAD = 4;
     
    Le prog principal est lancé
     
       Le thread1 est lancé.
       Le thread2 est lancé.
       Le thread3 est lancé.
       Pas besoin du thread4
     
       i = 1
       Lancement de la boucle d'attente jusqu'à currentThread = 3
         i=1 : Premier tour de boucle : Le thread 1 a été attendu (currentThread = 2)
         i=2 : Deuxième tour de boucle : Le thread 2 c'est terminé avant le join. (currentThread = 1). Le join se termine donc.
       La boucle sort puisque i = 2 >  currentThread = 1
     
       Le thread 3 n'a pas été attendu.
     
    Le prog principal se termine
    Pour que cela fonctionne il faut que je lock dans la boucle d'attente le currentThread pour qu'il garde toujours la valeur initial 3. Mais du coup les thread ne peuvent plus modifier cette valeur pour l'incrémenter/décrémenter et donc dead lock.

    La solution du threads[i] != NULL me chatouille aussi un peu car en fait threads est un tableau de pthread_t et comme je ne vois pas bien à quoi correspond le type pthread_t j'ai peur de faire une comparaison entre une poire et une pomme.
    D'ailleurs le compilo semble dire que pthread_t serait de type int et donc une comparaison entre un pointeur et un int c'est pas terrible du tout .

    A quoi dois-je comparer threads[i] à votre avis , -1 ?

  5. #5
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    C'est tout con, il suffit de compter le nombre de pthreads que tu as créé (et pas le nombre de threads actifs), et de faire une boucle avec le join comme tu l'as proposé.

  6. #6
    Membre confirmé
    Inscrit en
    Décembre 2003
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 99
    Par défaut
    Tu veux dire que j'ai un autre compteur que j'incrémente après chaque appel à pthread_create et que je boucle jusqu'à ce compteur dans la boucle d'attente ?

    Je pense pas que ça marche car ce compteur peut être à 10 alors qu'au moment de boucle j'ai que 3 thread en cours et donc le pthread_join (threads [4], NULL) va faire un segfault.

    Qu'en penses-tu ?

  7. #7
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Si, ça marchera. Tu peux tout à fait (et d'ailleurs, tu dois) faire un pthread_join() sur un thread qui a déjà terminé. En supposant évidemment que n'a pas créé tes thread en mode détaché.

    Par défaut, quand un thread termine, la lipthread garde quelques informations sur ce thread (en particulier son return code) de façon à ce qu'il puisse être "joiné". La totalité des ressources n'est libérée qu'après le join.

  8. #8
    Membre confirmé
    Inscrit en
    Décembre 2003
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 99
    Par défaut
    Je viens de tester et ça fait bien un segfault. Avec gdb et la backtrace on voit qu'il plante sur pthread_join(0,NULL);

    A noter qu'à la fin de chaque thread je fais un pthread_exit(NULL).
    Peut-être que les ressources dont tu parles sont libérées par cet appel.
    Je ne touche pas aux attributs du thread, par défaut il me semble que les threads sont "joinable"

    En fouillant dans les headers, j'ai vu que pthread_t est un unsigned long int.
    Avec gdb j'ai vu que mon tableau est initialisé avec des 0.
    J'ai donc remplacé le if (threads[i] != NULL) par if (threads[i] != 0)

    Ça marche mais c'est pas très portable

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Pthread et semaphores
    Par Yabo dans le forum Linux
    Réponses: 9
    Dernier message: 30/03/2008, 00h09
  2. Des problemes avec ces threads <pthread.h>
    Par nasamad dans le forum GTK+ avec C & C++
    Réponses: 26
    Dernier message: 07/07/2006, 12h46
  3. pthread et mutex
    Par Nico65 dans le forum C++
    Réponses: 20
    Dernier message: 16/01/2005, 12h30
  4. PB sortie standard avec les PTHREAD !!!
    Par djspit dans le forum C++
    Réponses: 15
    Dernier message: 19/11/2004, 01h17
  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