Le meilleur moyen de démarrer un thread en tant que membre d’une classe C ++?

StackOverflow https://stackoverflow.com/questions/86046

  •  01-07-2019
  •  | 
  •  

Question

Je me demande quel meilleur moyen de démarrer un pthread membre d'une classe C ++? Ma propre approche suit comme réponse ...

Était-ce utile?

La solution

J'utilise généralement une fonction membre statique de la classe et utilise un pointeur sur la classe comme paramètre void *. Cette fonction peut alors effectuer un traitement de thread ou appeler une autre fonction membre non statique avec la référence de classe. Cette fonction peut ensuite référencer tous les membres de la classe sans syntaxe compliquée.

Autres conseils

Ceci peut être fait simplement en utilisant la bibliothèque boost, comme ceci:

#include <boost/thread.hpp>

// define class to model or control a particular kind of widget
class cWidget
{
public:
void Run();
}

// construct an instance of the widget modeller or controller
cWidget theWidget;

// start new thread by invoking method run on theWidget instance

boost::thread* pThread = new boost::thread(
    &cWidget::Run,      // pointer to member function to execute in thread
    &theWidget);        // pointer to instance of class

Notes:

  • Ceci utilise une fonction membre de classe ordinaire. Il n’est pas nécessaire d’ajouter des membres statiques supplémentaires qui déroutent votre interface de classe
  • Incluez simplement boost / thread.hpp dans le fichier source où vous démarrez le fil. Si vous débutez avec boost, vous pouvez ignorer le reste de ce paquet volumineux et intimidant.

En C ++ 11, vous pouvez faire de même, mais sans boost

// define class to model or control a particular kind of widget
class cWidget
{
public:
void Run();
}

// construct an instance of the widget modeller or controller
cWidget theWidget;

// start new thread by invoking method run on theWidget instance

std::thread * pThread = new std::thread(
    &cWidget::Run,      // pointer to member function to execute in thread
    &theWidget);        // pointer to instance of class

Vous devez l'amorcer à l'aide du paramètre void *:

class A
{
  static void* StaticThreadProc(void *arg)
  {
    return reinterpret_cast<A*>(arg)->ThreadProc();
  }

  void* ThreadProc(void)
  {
    // do stuff
  }
};

...

pthread_t theThread;
pthread_create(&theThread, NULL, &A::StaticThreadProc, this);

J'ai utilisé trois des méthodes décrites ci-dessus. Lorsque j'ai utilisé pour la première fois le threading en c ++, j'utilisais les fonctions membres statiques , puis les fonctions ami et enfin les bibliothèques BOOST . Actuellement, je préfère BOOST. Au cours des dernières années, je suis devenu le bigot de BOOST.

BOOST est au C ++ comme le CPAN est au Perl. :)

La bibliothèque boost fournit un mécanisme de copie qui facilite le transfert des informations sur les objets. au nouveau fil. Dans l'autre exemple, boost :: bind sera copié avec un pointeur, qui vient également d'être copié. Il faudra donc veiller à la validité de votre objet pour éviter un pointeur en suspens. Si vous implémentez operator () et fournissez un constructeur de copie à la place et transmettez directement l'objet, vous n'avez pas à vous en soucier.

Une solution bien plus agréable, qui évite beaucoup de problèmes:

#include <boost/thread.hpp>

class MyClass {
public:
        MyClass(int i);
        MyClass(const MyClass& myClass);  // Copy-Constructor
        void operator()() const;          // entry point for the new thread

        virtual void doSomething();       // Now you can use virtual functions

private:
        int i;                            // and also fields very easily
};
MyClass clazz(1);
// Passing the object directly will create a copy internally
// Now you don't have to worry about the validity of the clazz object above
// after starting the other thread
// The operator() will be executed for the new thread.
boost::thread thread(clazz);             // create the object on the stack

L'autre exemple de boost crée l'objet thread sur le tas, bien que cela n'ait aucun sens de le faire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top