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

POSIX C Discussion :

Attendre la fin de tous les threads


Sujet :

POSIX C

  1. #1
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 741
    Points
    3 741
    Billets dans le blog
    12
    Par défaut Attendre la fin de tous les threads
    Bonjour,

    En Java ou C#, lorsqu'on lance des threads, le programme principal ( le main() ) ne se termine pas tant que tous les threads (sauf celui du main() ) est toujours en cours d'exécution.

    Avec un thread en C sous Unix, ce n'est pas le cas ! Il faut forcément faire un pthread_join sur le thread... Sauf que la fonction pthread_join est bloquante.

    Je souhaiterais donc savoir comment faire pour que le main() ne s'arrête pas, tant que TOUS les threads lancés (que ce soit à partir du main() , ou d'une fonction qui lance un thread à partir d'un autre thread) ne sont pas terminés.

    Cordialement,
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  2. #2
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2012
    Messages : 62
    Points : 162
    Points
    162
    Par défaut
    Bonjour,
    Une solution facile est de mettre tous tes threads dans un tableau.
    A la fin de ton programme, il te suffit alors de faire une boucle pour parcourir ce tableau et exécuter pthread_join sur chaque thread.

    [EDIT]
    Je pense avoir mal compris ton problème, tu veux pouvoir demander aux threads de s'arrêter pour que ton programme puisse lui aussi s'arrêter correctement ?

    Si c'est le cas regarde du coté de la fonction pthread_cancel qui permet de demander un thread de s'arreter. Par contre, si ton thread avait alloué de la mémoire, je ne sais pas comment la libérer.
    Si ton thread est une boucle "infinie" avec un temps d’exécution raisonnable, tu peux utiliser une variable passée en argument de ton thread pour lui demander de sortir de cette boucle et se terminer normalement.

  3. #3
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Si tu crées n threads, dans le main(), tu peux en effet faire n pthread_join() pour en attendre la fin. Le fait que cette fonction soit bloquante ne pose pas de problème à ma connaissance. Au pire, tu tomberas peut-être à un moment à tenter de joindre un thread déjà terminé, ce qui semble se gérer simplement.

    Je présume que ton problème réel est le cas où de ces threads lancent lui aussi un thread et ne fait pas un pthread_join() ?

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 628
    Points : 10 553
    Points
    10 553
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Je présume que ton problème réel est le cas où de ces threads lancent lui aussi un thread et ne fait pas un pthread_join() ?
    Oui mais dans ce cas tu peux coder un singleton global qui gère tous les threads identifié par un iD: add_thread cancel_thread wait_threads wait_all_threads

    Et si tu veux avoir à la fois l'attente bloquante et non bloquante pour la fin des threads, tu peux faire un singleton-Observateur register_end_threads

  5. #5
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 741
    Points
    3 741
    Billets dans le blog
    12
    Par défaut
    Bonsoir,

    @schonai
    Une solution facile est de mettre tous tes threads dans un tableau.
    Oui, mais dans le cas où j'exécute des threads partout dans le programme, je ne peux pas m'amuser à passer un tableau de thread dans les paramètres de toutes mes fonctions.


    @schonai
    tu veux pouvoir demander aux threads de s'arrêter pour que ton programme puisse lui aussi s'arrêter correctement ?
    Non surtout pas de cancel ou stop sur les threads. Je souhaiterais que mon main() s'arrête de lui-même, une fois que tous les pthread_create() lancés dans le programme soient terminés (comportement par défaut en Java ou C#).


    @Bktero
    Le fait que cette fonction soit bloquante ne pose pas de problème à ma connaissance.
    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
    void affiche_3_fois(int j){
        int k = 0;
        for(; k < 3; k++){
            printf(" %d ", j);
            sleep(1000);
        }
    }
     
    int main(){
        printf("Début du programme\n");
        int i = 0;
        for(; i < 10; i++){
            // Création d'un nouveau thread dans chaque itération :
            pthread_t t;
            pthread_create(&t, NULL, affiche_3_fois, &i);
        }
     
        printf("\nFin du programme");
        return 0;
    }
    Je ne peux malheureusement pas tester le code dessus, car je n'ai pas d'environnement UNIX/Linux.
    Aussi je ne sais pas quel comportement ce code peut avoir, sachant que pthread_create est asynchrone, et que la variable t et i sont locales à la boucle for.
    Si ce code fonctionne (supposition)... le programme est en théorie censé afficher 1 nombre par seconde durant 30 secondes... du moins en Java et C# c'est le cas, sans même avoir besoin d'utiliser les méthodes join qui font parti de la classe Thread...
    Exemple de séquence :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Début du programme
    0 0 1 1 0 2 1 2 4 3 4 3 3 
    Fin du programme 2 5 4 5 5 6 7 6 6 8 7 9 8 9 8 7 9
    Qu'en est-t-il du C ? Est-ce que le programme affiche en partie des nombres et s’interrompt brutalement ? Ou bien le comportement est comme en Java et C# ?


    @Bktero
    Je présume que ton problème réel est le cas où de ces threads lancent lui aussi un thread et ne fait pas un pthread_join() ?
    Oui il y a de ça. Rien n'empêche un thread de lancer un autre thread. Donc comment faire en sorte que le main() ne s'interrompt pas tant que tous ces threads sont en cours d'exécution ?


    Merci pour vos réponses.
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  6. #6
    Membre expérimenté Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Points : 1 396
    Points
    1 396
    Par défaut
    Il faut que tu fasses un join à chaque fois que tu lances un thread. Ce que je veux dire c'est que le join ne se fera pas nécessairement dans le main. De cette manière tu n'auras pas de thread orphelin (dont le père s'est terminé avant), et du coup, récursivement, le main ne s'arrêtera pas avant les autres threads vu que c'est une fonction dans le thread root (principal).

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Tu fais 2 demandes contradictoires dans le même message : d'un côté que le main() s'arrête sans que les autres threads s'arrêtent et de l'autre que le main() ne se termine pas tant que les threads ne sont pas terminés. Si tu veux retrouver un comportement à la Java, tu peux regarder des detachable threads. Regarde cette section d'un cours Developpez : http://gkemayo.developpez.com/tempsr...osix/#LIII-B-3

  8. #8
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 149
    Points : 28 116
    Points
    28 116
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    Je ne peux malheureusement pas tester le code dessus, car je n'ai pas d'environnement UNIX/Linux.
    Heureusement, tu peux le tester gratuitement en ligne : https://www.google.fr/#q=compile+C+online
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  9. #9
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 741
    Points
    3 741
    Billets dans le blog
    12
    Par défaut
    Bonjour,


    Je rectifie juste une erreur grosse comme la lune par rapport à mon message précédent :
    le programme est en théorie censé afficher 1 nombre par seconde durant 30 secondes...
    =>
    le programme est en théorie censé afficher plusieurs nombres par seconde durant 3 secondes... avec 30 nombres au total

    @Trademark
    Il faut que tu fasses un join à chaque fois que tu lances un thread
    C'est censé être le comportement par défaut, mais on peut remplacer le mode JOIN par un autre avec le 2ème paramètre de la fonction pthread_create.


    @Trademark
    De cette manière tu n'auras pas de thread orphelin (dont le père s'est terminé avant)
    Je pense qu'il y a une confusion avec les processus (les fork). Avec les processus légers (les thread), il n'y a pas de thread "parent" ou "enfant". Les threads ne sont pas liés.



    @Bktero
    Tu fais 2 demandes contradictoires dans le même message : d'un côté que le main() s'arrête sans que les autres threads s'arrêtent et de l'autre que le main() ne se termine pas tant que les threads ne sont pas terminés.
    Je me suis peut-être mal exprimé en faisant référence au main(). Mais ce que je souhaiterais, c'est qu'une fois arrivé à la dernière accolade du programme (l'accolade de fermeture de la fonction main() ), mon programme ne s'arrête pas brutalement, et que tous les threads en cours d'exécution soient terminés "normalement" (pas de cancel).

    @Bktero
    Si tu veux retrouver un comportement à la Java, tu peux regarder des detachable threads.
    Je suis allé dans le code source de Java (implémentation OpenJDK) pour mieux comprendre le comportement, et en effet on peut y lire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // Fichier os/linux/vm/os_linux.cpp
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
     
    [...]
     
    pthread_t tid;
    int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);

    @gangsoleil
    Je le savais déjà, mais en ayant utilisé ideone, il me semble qu'on n'a pas le droit d'utiliser les fonctions systèmes.


    Je vous remercie pour vos réponses. Je pense maintenant avoir une meilleure idée des threads en C avec Posix. N'hésitez pas à faire part de vos remarques, je mettrais le sujet en résolu d'ici la fin de la semaine.


    Cordialement,
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  10. #10
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Je suis allé dans le code source de Java (implémentation OpenJDK) pour mieux comprendre le comportement, et en effet on peut y lire
    C'est bourrin mais c'est une bonne idée !

    J'ai eu le nez creux sur ce coup là

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    Je me suis peut-être mal exprimé en faisant référence au main(). Mais ce que je souhaiterais, c'est qu'une fois arrivé à la dernière accolade du programme (l'accolade de fermeture de la fonction main() ), mon programme ne s'arrête pas brutalement, et que tous les threads en cours d'exécution soient terminés "normalement" (pas de cancel).
    Dans ce cas, il me semble qu'à moins d'être sous Windows, le seul moyen est de mettre une boucle de pthread_join() juste avant cette dernière accolade: pthread n'a pas, à ma connaissance, de notion de "laisser le premier thread se terminer sans tuer tous les autres".

    Et même sous Windows, ce n'est pas recommandé parce que trop de fonctions créent des threads d'arrière-plan que l'utilisateur ne contrôle pas (.Net résout le problème en ayant deux sortes de threads).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 741
    Points
    3 741
    Billets dans le blog
    12
    Par défaut
    Bonsoir,

    @Médinoc
    Dans ce cas, il me semble qu'à moins d'être sous Windows, le seul moyen est de mettre une boucle de pthread_join() juste avant cette dernière accolade: pthread n'a pas, à ma connaissance, de notion de "laisser le premier thread se terminer sans tuer tous les autres".
    D'accord, mais si j'ai des threads qui lancent d'autres threads dans une boucle ? Comment mettre un pthread_join() à la fin du main sachant qu'on n'a pas la même portée ?
    "laisser le premier thread se terminer sans tuer tous les autres" -> Le "premier thread" ?... je suis perdu, vous faite bien référence au main() ?


    Et même sous Windows, ce n'est pas recommandé parce que trop de fonctions créent des threads d'arrière-plan que l'utilisateur ne contrôle pas (.Net résout le problème en ayant deux sortes de threads).
    Vous faite peut-être référence aux Processus et Thread de Windows (cf: documentation)... mais je ne vois pas le rapport avec le sujet. Même si les detached thread sont déconseillées, les langages de haut niveau semblent ne pas s'abstenir pour les utiliser.
    Aussi je ne vois pas en quoi .NET résout le problème, .NET n'est pas magique (tout comme Java), pour Windows derrière il y a la lib C pour les threads Win32. La seule différence que j'ai constaté par rapport à Linux est que la fonction fork() n'existe pas sous Windows.



    En ce moment j'ai accès à un poste sous Linux, et voici mes tests (j'aurais deux nouvelles questions, A et B) :
    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
    #include <stdlib.h>
    #include <stdio.h>
    #include <pthread.h>
     
     
    void* affiche1(){
        int i;
        for(i = 0; i < 3; i++){
            printf("%d", i);
            sleep(1); // Attente de 1 seconde
        }
    }
     
    void* affiche2(){
        int i;
        for(i = 3; i < 6; i++){
            printf("%d", i);
            sleep(1); // Attente de 1 seconde
        }
    }
     
    int main(int argc, char *argv[]){
     
        // Mode JOIN
        pthread_t thread1;
        pthread_create(&thread1, NULL, affiche1, NULL);
        pthread_join(thread1, NULL);
        printf("Hello");
        /* Analyse :
            - Sans la fonction join, le programme s'arrête immédiatement, sans rien afficher.
            - Avec la fonction join, le programme attend trois secondes, affiche "012Hello3" d'un seul coup, et s'arrête.
     
            Question A : Pourquoi l'affichage n'est pas en temps réel (seconde par seconde) ? Pourquoi 012Hello s'affiche d'un seul coup ?
            PS : le "3" représente le chiffre affiché par la fonction affiche2(), et non pas affiche1() !
        */
     
     
        // Mode DETACHED
        pthread_t thread2;
        pthread_attr_t detachedAttr;
        pthread_attr_init(&detachedAttr);
        pthread_attr_setdetachstate(&detachedAttr, PTHREAD_CREATE_DETACHED);
        pthread_create(&thread2, &detachedAttr, affiche2, NULL);
        // Pas de join possible sur un thread en mode detached
        /* Analyse :
            - Malgré le mode PTHREAD_CREATE_DETACHED, le programme se termine avant la fin de thread2.
            
            Question B : Qu'est-ce qui m'assure que mon thread2 va jusqu'au bout de sa tâche en arrière plan (traiter le "4" et "5" après le "3"), après la fin du main ?
        */
     
        return 0; // On quitte la console  
    }
    Les questions A et B sont dans les commentaires du code.


    Cordialement,
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  13. #13
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Pourquoi 012Hello s'affiche d'un seul coup ?
    Parce la sortie standard est bufferisée. Tu printes sans retour à la ligne donc il n'y a pas de flux. Rajoute un flush ou un \n à la fin de ton printf().

    J'essayerai de penser à tester ça demain sous Linux.

  14. #14
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    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
    #include <pthread.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
     
     
    void* affiche1(){
        int i;
        for(i = 0; i < 3; i++){
            printf("%d\n", i);
            sleep(1); // Attente de 1 seconde
        }
    }
     
    void* affiche2(){
        int i;
        for(i = 3; i < 6; i++){
            printf("%d\n", i);
            sleep(1); // Attente de 1 seconde
        }
    }
     
    int main(int argc, char *argv[]){
     
        // Mode JOIN
        pthread_t thread1;
        pthread_create(&thread1, NULL, affiche1, NULL);
        pthread_join(thread1, NULL);
        printf("Thread has been joined\n");
     
     
        // Mode DETACHED
        pthread_t thread2;
        pthread_attr_t detachedAttr;
        pthread_attr_init(&detachedAttr);
        pthread_attr_setdetachstate(&detachedAttr, PTHREAD_CREATE_DETACHED);
        pthread_create(&thread2, &detachedAttr, affiche2, NULL);
        printf("Thread will not be joined, exiting main()\n");
     
        pthread_detach(pthread_self());
        pthread_exit(NULL);
        //return 0; // On quitte la console  
    }
    $:~/Documents$ c99 test_thread.c -lpthread && ./a.out 
    0
    1
    2
    Thread has been joined
    Thread will not be joined, exiting main()
    3
    4
    5
    $:~/Documents$ echo $?
    0
    
    Voir : http://www.domaigne.com/blog/computing/the-main-thread/
    Je ne suis pas sûr que le pthread_exit() soit totalement utile, à voir. Aucun de mes threads n'appellent exit() non plus. Mais ça fait le taf.

  15. #15
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Merci beaucoup pour ce lien.

    Donc, c'est semblable à Windows pour ce qui est du premier thread.


    Citation Envoyé par Gugelhupf Voir le message
    Vous faite peut-être référence aux Processus et Thread de Windows (cf: documentation)... mais je ne vois pas le rapport avec le sujet. Même si les detached thread sont déconseillées, les langages de haut niveau semblent ne pas s'abstenir pour les utiliser.
    Aussi je ne vois pas en quoi .NET résout le problème, .NET n'est pas magique (tout comme Java), pour Windows derrière il y a la lib C pour les threads Win32.
    Je ne fais pas référence aux detached thread, mais au fait que si tu utilises certaines fonctions comme celles liées au thread pool (QueueUserWorkItem() etc.) ou certaines liées à COM, la bibliothèque correspondante va créer des threads qui ne se terminent jamais: Ils bloquent indéfiniment sur une fonction d'attente, et il n'y a pas de fonction TellAllWindowsThreadsToStopWaitingAndExitCleanly().
    Résultat, avec ça la méthode "pthread_exit() dans main, puis laisser tous mes threads se terminer proprement, le processus finira de lui-même" ne marche pas, et il faut forcément qu'au moins un de tes threads appelle exit().

    Le framework .Net résout (ou contourne) le problème en marquant tous ces threads-là comme threads "faibles", et en surveillant (et comptant) les threads managés qui se terminent: Quand le dernier thread "fort" d'un processus se termine, le framework appelle ExitProcess(), tuant tous les threads "faibles" encore là.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  16. #16
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 741
    Points
    3 741
    Billets dans le blog
    12
    Par défaut
    Bonsoir,

    Je pense que je fais une erreur en essayant de comparer les threads Posix en C et C++11, et les threads proposées par des langages tels que Java et C#, car ces derniers ne sont pas exécutés de la même manière.

    Néanmoins, j'aurais vraiment une dernière questions avant de fermer ce sujet :
    Malgré avoir lu la documentation, je ne comprends pas du tout à quoi servent (avec l'utilité et les limites au niveau de la portée), et quand il faut utiliser les 2 instructions suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pthread_detach(pthread_self());
    Cordialement,
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  17. #17
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Je pense que c'est pour éviter des fuites de mémoire.

    L'API de pthread doit permettre à une bibliothèque d'allouer dynamiquement une structure de données associée au thread. Cette structure de donnée est libérée par pthread_join() si un thread n'est pas détaché, ou dès la fin du thread si celui-ci l'est.

    Donc, si on ne fait jamais de pthread_join() sur un thread non-détaché, la mémoire allouée est leakée.

    J'ai du mal à comprendre pour pthread_exit() par contre, sauf dans le main() pour éviter le exit() automatique. Je ne pense pas que ce soit une question de libération de mémoire, vu qu'un thread peut faire ça quand la start_routine passée à pthread_create() retourne.

    Editl:
    Citation Envoyé par doc de pthread_exit
    The process exits with an exit status of 0 after the last thread has been terminated. The behaviour is as if the implementation called exit() with a zero argument at thread termination time.
    Ça par contre, c'est différent de ce que fait l'API Windows, qui termine avec le code de sortie du dernier thread.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  18. #18
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 741
    Points
    3 741
    Billets dans le blog
    12
    Par défaut
    Alors je viens de faire des tests, et je comprends à quoi sert le pthread_exit, c'est tout bête : Cela sert à quitter la fonction courante en retourner une valeur (de n'importe quel type). Dans notre cas il est intéressant de placer pthread_exit dans une fonction exécutée par un pthread_create ( ex: 'affiche' ).
    C'est un peu comme la valeur de retour d'un "future".

    pthread_detach sert à faire passer un thread du mode JOIN au mode DETACHED.
    pthread_self sert à retourner l'id du thread courant.
    Donc dans l'exemple pthread_detach(pthread_self()) sert, je crois, à rendre le thread principal (main) en mode DETACHED.

    Maintenant je ne suis toujours pas sorti de l'auberge, car je ne vois toujours pas comment je pourrais terminer proprement tous mes threads (dont ceux qui sont exécutés par d'autres threads), sans que le main() se termine.
    Le but étant d'avoir un comportement similaire aux threads en Java & C#.

    PS: Si une personne qui a de l'expérience à ce sujet (les threads en C & Java | C#), n'hésitez pas à répondre à ce sujet et m'envoyer un mp pour me notifier. Je fermerai ce sujet d'ici la fin de la semaine.


    Cordialement,
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  19. #19
    Membre expérimenté Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Points : 1 396
    Points
    1 396
    Par défaut
    Je ne pense pas qu'il y ait 36 solutions. Soit tu encapsules la création de thread qui en plus de créer le thread, le stocke dans un environnement (que tu passes à chaque fonction, ce qui peut être lourd si tu n'as pas de notion d'environnement ; en plus il faut protéger la structure pour les accès concurrents). Soit tu pars du principe que chaque thread termine ses propres fils (conceptuellement — on s'en fiche que techniquement il n'y a pas de relation parent-enfant) et du coup par induction, tu n'auras qu'à faire un join sur les threads que tu auras lancé dans le main (qui eux-mêmes ne se termineront pas avant d'avoir attendu leurs propres "fils").

  20. #20
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Donc dans l'exemple pthread_detach(pthread_self()) sert, je crois, à rendre le thread principal (main) en mode DETACHED.
    Oui.


    A quoi sert pthread_exit() ?
    C'est clairement indiqué dans la documentation :
    http://linux.die.net/man/3/pthread_join
    pthread_join() copies the exit status of the target thread (i.e., the value that the target thread supplied to pthread_exit(3))
    On peut aussi lire :
    Performing a return from the start function of any thread other than the main thread results in an implicit call to pthread_exit(), using the function's return value as the thread's exit status.
    Dans une autre documentation, il y a aussi cette phrase intéressante:
    http://linux.die.net/man/3/pthread_exit
    To allow other threads to continue execution, the main thread should terminate by calling pthread_exit() rather than exit(3).

    Maintenant je ne suis toujours pas sorti de l'auberge, car je ne vois toujours pas comment je pourrais terminer proprement tous mes threads (dont ceux qui sont exécutés par d'autres threads), sans que le main() se termine.
    Le but étant d'avoir un comportement similaire aux threads en Java & C#.
    Là où tu fais fausse route, c'est sur le comportement de Java et la manière que tu as de comparer ce fonctionnement aux threads Posix. En Java, le main() s'arrête si tu ne fais pas un join() des threads lancés et il n'y a pas (en tout cas, je ne vois rien de ce genre dans la doc : http://docs.oracle.com/javase/7/docs...ng/Thread.html), de threads détachables. La JVM elle ne s'arrête pas. Ce n'est pas du tout pareil de vouloir en C que le main() ne s'arrête pas. Je rejoins l'avis de Trademark sur ce point : il faudrait que tu fasses ta propre API de threads, qui utiliserait un compteur pour savoir combien de threads sont encore vivants. Le main() lancerait finalement un premier thread, qui lancerait d'autres, qui se terminerait, mais main() continuera d'attendre les autres threads. De ce que j'ai pu lire pour écrire mon précédent message, je ne vois pas d'autres solutions. Qu'as-tu à ce sujet dans le source d'OpenJDK ?


    PS: Si une personne qui a de l'expérience à ce sujet (les threads en C & Java | C#), n'hésitez pas à répondre à ce sujet et m'envoyer un mp pour me notifier. Je fermerai ce sujet d'ici la fin de la semaine.
    Tu peux demander à t'abonner au sujet et tu pourras ainsi recevoir un mail en cas de réponse.

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

Discussions similaires

  1. Comment arrêter tous les Threads ?
    Par Ceubex dans le forum Général Java
    Réponses: 9
    Dernier message: 04/01/2011, 14h10
  2. Réponses: 8
    Dernier message: 19/11/2010, 11h01
  3. Jonas freezé, tous les threads sont occupés
    Par Bouhaouala dans le forum JOnAS
    Réponses: 1
    Dernier message: 07/11/2009, 23h36
  4. Réponses: 7
    Dernier message: 04/02/2008, 16h49
  5. Comment attendre que tous les thread lancés soient morts pour lancer une action.
    Par rgesnot dans le forum Concurrence et multi-thread
    Réponses: 2
    Dernier message: 31/03/2007, 20h27

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