44 votes

Utilisation d'un thread boost et d'une fonction de classe non statique

J'ai donc fait quelques recherches, et ont constaté que vous pouvez créer un boost::thread de l'objet et de l'avoir commencer avec un non-statique de la classe de fonction à l'aide de "ce" et boost::bind etc. Il n'a vraiment pas beaucoup de sens pour moi et pour tous les exemples que j'ai pu trouver a le boost::thread objet lancé dans la même classe que la fonction elle était de commencer avec ce qui pourrait être utilisé. Je ne suis toutefois le lancement du thread dans une classe différente, alors je crains que par l'utilisation de "ce", je vais dire le "il" est à partir de la classe je suis de la création du thread, plutôt que celui de la fonction (je suis probablement mal, j'ai besoin d'en savoir plus sur ce "ce" gars). Voici un exemple de ma source, je vais avoir le problème avec.

ANNGUI.h

classe ANNGUI
{
privé:
 boost::thread *GUIThread;
 Principal *GUIMain;
public:
 // Crée l'ensemble de l'interface graphique et de tous les sous-parties.
 int CreateGUI();
}

ANNGUI.cpp

int ANNGUI::CreateGUI()
{
 GUIMain = new Main();
 GUIThread = new boost::thread(GUIMain->MainThreadFunc);
};

Ce n'est pas la source, mais je pense que mon problème est là, quelque part, je sais que j'ai à faire face à "ce" en quelque sorte, mais je ne suis pas sûr de savoir comment. Je Pourrais utiliser une fonction statique, mais je n'ai pas vraiment envie de faire mes variables statique. Merci.

Aussi, Est-il une bonne ressource pour l'utilisation de toutes les bibliothèques boost? Le site web de la documentation semble bon, mais au dessus de ma tête.

83voto

Charles Salvia Points 28661

L' this mot-clé est utilisé avec boost::bind lorsque la fonction de l'objet que vous êtes en train de créer est lié à un objet de la fonction membre. Les fonctions de membres ne peut pas exister en dehors de cas, de sorte que lors de la création d'un foncteur objet en dehors d'une fonction membre avec boost::bind, vous avez besoin d'un pointeur vers une instance. C'est exactement ce que l' this mot-clé est en réalité. Si vous utilisez l' this mot-clé à l'intérieur d'une fonction membre d'une classe, ce que vous obtenez est un pointeur sur l'instance courante de la classe.

Si vous vous appelez bind de l'extérieur d'une fonction membre de classe, vous pourriez dire quelque chose comme:

int main()
{
  Foo f;
  boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, &f));
}

Ici, nous utilisons des Foo::une_fonction que notre fonction de thread. Mais nous ne pouvons pas utiliser this parce que nous sommes appelant bind de main. Mais la même chose pourrait être réalisé à l'aide de this si on appelait bind de l'intérieur d'une fonction membre de Foo, comme suit:

void Foo::func1()
{
  boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, this));
}

Si une fonction membre statique, ou simplement régulier (non-membre) de la fonction, alors vous n'avez pas besoin d'un pointeur d'instance à tous. Vous faites juste:

boost::thread* thr = new boost::thread(some_regular_function);

40voto

maxschlepzig Points 3578

Comme d'autres l'ont mentionné, lorsque vous voulez appeler une méthode de l'objet dans un nouveau thread, vous devez fournir l'adresse de cet objet. Mais vous n'avez pas besoin d'appeler boost::bind, vous pouvez utiliser la surcharge boost::thread constructeur comme ceci:

GUIThread = new boost::thread(&Main::MainThreadFunc, GUIMain);

Si la méthode est dans la même classe que vous l'utilisez this pour obtenir l'adresse de l'instance en cours, par exemple:

t = new boost::thread(&myclass::compute, this);

Si la méthode des paramètres, vous pouvez spécifier après le deuxième argument, par exemple:

t = new boost::thread(&myclass::compute, this, p1, p2);

3voto

villintehaspam Points 4470

boost :: bind est votre ami (il peut parfois avoir un moyen rude de le montrer)!

utiliser GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain));

puis faites de votre MainThreadFunc un membre régulier. Cela signifie que vous pouvez utiliser les variables d'instance directement comme vous le feriez normalement.

Quelque chose comme ça:

 class GUIMain {
public:
  GUIMain() : m_Member(42) {}

  void MainThreadFunc() {
    // use all members as you would normally do
    std::cout << m_Member << std::endl;
  }

private:
  int m_Member;
};
 

3voto

Giuseppe Ottaviano Points 1638

Dans un tel cas, il est utile de penser à des non-membre statique de fonctions comme gratuit des fonctions qui prennent l' this comme premier paramètre, par exemple dans votre cas void MainThreadFunc(Main* this).

boost::thread accepte un nullary foncteur, de sorte que vous avez à passer un nullary foncteur qui contient une référence à l'instance GUIMain et des appels GUIMain->MainThreadFunc ce qui, vu comme je l'ai expliqué ci-dessus, serait quelque chose comme MainThreadFunc(GUIMain).

Coup de pouce (et maintenant aussi en C++ avec TR1) fournit des aides pour créer de tels foncteurs, à savoir l' boost::bind (ou, alternativement, boost::lambda::bind). L'expression boost::bind(f, arg1, arg2, ...) signifie "retourner un nullary foncteur qui demande f(arg1, arg2, ...)".

Cela dit, vous pouvez utiliser l'expression suivante pour créer le thread:

GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain))

1voto

Bulletmagnet Points 165

Si votre objet est un foncteur, c'est-à-dire qu'il a operator() , vous pouvez en passer une instance à boost::thread . Le operator() n'a pas besoin d'être statique. Par exemple:

 #include <boost/thread.hpp>

struct th {
    void operator()();
};

void th::operator()()
{
    for (;;) {
        // stuff
    }
}

int main()
{
    th t;
    boost::thread my_thread( t ); // takes a copy of t !
    my_thread.join(); // blocks
    return 0;
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X