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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 326
    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 326
    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 éprouvé
    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
    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
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 496
    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 confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 777
    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 777
    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 326
    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 326
    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 Expert 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
    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
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 496
    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 150
    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 150
    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 326
    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 326
    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

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

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