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

Boost C++ Discussion :

Fonction boost::thread::join() et indépendance d'un thread


Sujet :

Boost C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Par défaut Fonction boost::thread::join() et indépendance d'un thread
    Bonjour
    je débute plus ou moins en matière de Boost et de threads.
    J'attaque par le chapitre 6 Multithreading du livre de Boris Schäling (voir http://en.highscore.de/cpp/boost/index.html ).
    A la sous-section 6.2, l'auteur écrit ceci :
    As seen in the above example, a particular thread can be accessed via a variable such as t in order to e.g. wait for its termination using the join() method. However, the thread will continue to execute even if t loses its scope and is destroyed. A thread always binds to a variable of type boost::thread in the beginning, but once created, depends no longer on it.
    Son exemple est le programme suivant ou un thread affiche 5 entiers à l'écran :

    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
    #include <boost/thread.hpp> 
    #include <iostream> 
    #include <fstream>
     
    void wait(int seconds) 
    { 
      boost::this_thread::sleep(boost::posix_time::seconds(seconds)); 
    } 
     
    void thread() 
    { 
      for (int i = 0; i < 5; ++i) 
      { 
        wait(1); 
        std::cout << i << std::endl;
      } 
    } 
     
    int main() 
    { 
      boost::thread t(thread); 
      t.join();
    }
    J'avais donc cru comprendre que la ligne finale du main était en quelque sorte ici facultative.
    Toutefois si je la commente, le programme résultant n'affiche plus les entiers en console.
    Et si je remplace le contenu de la fonction thread() de façon à le rendre indépendant d'un affichage console (par exemple en effectuant simplement la création d'un fichier), il en va de même : si la ligne t.join(); est commentée pas de création de fichier...
    Du coup, je ne comprends plus très bien, d'après l'auteur le thread devrait continuer à s'exécuter indépendamment, même après la fin du main, mais ça ne semble pas être le cas. Ce que dit l'auteur est-il inexact ?

  2. #2
    Membre expérimenté Avatar de vikki
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    292
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 292
    Par défaut
    Salut,
    La citation que tu donnes est assez claire. Un objet de type boost::thread représente bien le thread créé et permet dans une certaine mesure d'interagir avec. Si l'objet boost::thread est détruit, le thread continue à s'exécuter mais tu n'y auras plus accès (le thread est alors dit "détaché"). La méthode join() retourne lorsque le thread termine son exécution, elle est donc indispensable dans code d'exemple. En effet, peut importe le nombre de thread ou l'état de leur exécution, quitter la fonction main() veut toujours dire la fin de ton programme et de TOUS les thread créés par celui ci.

  3. #3
    Membre très actif
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Par défaut
    Bon, merci, je retiens donc ceci :
    Citation Envoyé par vikki Voir le message
    peu importe le nombre de threads ou l'état de leur exécution, quitter la fonction main() veut toujours dire la fin de ton programme et de TOUS les thread créés par celui-ci.
    La phrase :
    However, the thread will continue to execute even if t loses its scope and is destroyed.
    semblait indiquer qu'après la fin du thread main, où justement le thread t 'loses its scope and is destroyed' le thread t pouvait continuer à s'exécuter.

    Mais en fait le thread main est le thread 'leader' du groupe de threads et quand le 'leader' est tué ses fils sont tués aussi, c'est ça ?

  4. #4
    Membre expérimenté Avatar de vikki
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    292
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 292
    Par défaut
    Mais en fait le thread main est le thread 'leader' du groupe de threads et quand le 'leader' est tué ses fils sont tués aussi, c'est ça ?
    La fonction main est le point d'entrée du programme, elle est appelée par le système d'exploitation à l"exécution du binaire. Quitter cette fonction signifie toujours la fin de l'exécution du programme et de tous les processus fils.

  5. #5
    Membre très actif
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Par défaut
    Pour en revenir à ma question initiale et à la réponse donnée plus haut :
    Citation Envoyé par vikki Voir le message
    La fonction main est le point d'entrée du programme, elle est appelée par le système d'exploitation à l"exécution du binaire. Quitter cette fonction signifie toujours la fin de l'exécution du programme et de tous les processus fils.
    il semblerait que ce soit un peu moins absolu, d'après ce que je vois ici :
    https://computing.llnl.gov/tutorials/pthreads/#Joining

    If main() finishes before the threads it has created, and exits with pthread_exit(), the other threads will continue to execute. Otherwise, they will be automatically terminated when main() finishes.

  6. #6
    Membre expérimenté Avatar de vikki
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    292
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 292
    Par défaut
    Es tu sûr que pthread_exit() n'est pas appelé en fin de main justement pour éviter de quitter celui-ci tant que tous les processus fils ne sont pas terminés?

  7. #7
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    De manière intéressante, le detach() optionnel sous boost deviendra obligatoire en C++0x : une thread qui est joinable quand elle entre dans son destructeur va provoquer un appel à std::terminate(). Du coup le comportement du programme sera on ne peut plus clair.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  8. #8
    Membre très actif
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Par défaut
    Oui, évidemment, tous les threads partagent un même espace mémoire alloué par le système d'exploitation et la fin du main() signifie la libération de cette zone et donc la fin des threads qui s'y meuvent...

  9. #9
    Membre expérimenté Avatar de vikki
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    292
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 292
    Par défaut
    De manière intéressante, le detach() optionnel sous boost deviendra obligatoire en C++0x : une thread qui est joinable quand elle entre dans son destructeur va provoquer un appel à std::terminate(). Du coup le comportement du programme sera on ne peut plus clair.
    Si j'ai bien compris, ca va obliger à modifier pas mal de code. A moins qu'il suffise d'un set_terminate avec un terminate_handler qui ne fait rien (j'ai du mal à voir les effets de bord)?

  10. #10
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par vikki Voir le message
    Si j'ai bien compris, ca va obliger à modifier pas mal de code. A moins qu'il suffise d'un set_terminate avec un terminate_handler qui ne fait rien (j'ai du mal à voir les effets de bord)?
    Modifier le code, modifier le code... C'est vite dit : il n'y a aucun code qui utilise std::thread a l'heure actuel (outre le code expérimental basé sur l'implémentation fournie dans les versions récentes de g++). Celui qui veut passer les thread de boost à std devra de toute façon modifier le code, donc l'impact supplémentaire n'est pas forcément très important.

    Le terminate handler est censé ne jamais terminer (en fait, un terminate handler peut juste afficher un diagnostique et quitter le programme ; la norme dit que la fonction ne peut pas retourner le contrôle à l'appelant. Ceci dit, g++ implemente le std::terminate ainsi : (dans le principe))

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    namespace std
    {
      void terminate()
      {
        if (__terminate_handler) __terminate_handler();
        exit(...);
      }
    }
    Du coup, même si le terminate handler ne fait pas ce qui est souhaitable vis à vis de la norme, le programme s'arrête quand même. Au niveau de la norme, il faudrait faire


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    namespace std
    {
      void terminate()
      {
        if (__terminate_handler) __terminate_handler();
        else exit(...);
      }
    }
    Ce qui forcerait le code de __terminate_handler() a quitter le programme, sous peine d'avoir un programme mal formé.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 15/11/2010, 14h21
  2. Réponses: 14
    Dernier message: 29/10/2010, 17h43
  3. boost::asio::ip::tcp::socket est elle thread safe ?
    Par nemodev dans le forum Boost
    Réponses: 4
    Dernier message: 24/02/2010, 13h08
  4. join et invoke dans les thread ne s'entendent pas
    Par andromeda dans le forum C#
    Réponses: 2
    Dernier message: 03/03/2009, 00h39
  5. Appel d'un fonction C sous Python et blocage des autres threads
    Par mkrzemin dans le forum Interfaçage autre langage
    Réponses: 3
    Dernier message: 07/02/2008, 14h52

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