Il modo migliore per avviare una discussione come membro di una classe C++?

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

  •  01-07-2019
  •  | 
  •  

Domanda

Mi chiedo il migliore modo per avviare un pthread che è membro di una classe C++?Il mio approccio segue come risposta...

È stato utile?

Soluzione

Di solito utilizzo una funzione membro statica della classe e utilizzo un puntatore alla classe come parametro void *.Tale funzione può quindi eseguire l'elaborazione del thread o chiamare un'altra funzione membro non statica con il riferimento alla classe.Quella funzione può quindi fare riferimento a tutti i membri della classe senza una sintassi scomoda.

Altri suggerimenti

Questo può essere fatto semplicemente utilizzando la libreria boost, in questo modo:

#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

Appunti:

  • Utilizza una normale funzione membro della classe.Non è necessario aggiungere ulteriori membri statici che confondono l'interfaccia della classe
  • Basta includere boost/thread.hpp nel file sorgente in cui inizi il thread.Se stai appena iniziando con il potenziamento, tutto il resto di quel pacchetto ampio e intimidatorio può essere ignorato.

In C++11 puoi fare lo stesso ma senza 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

Devi avviarlo utilizzando il parametro 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);

Ho usato tre dei metodi sopra descritti.Quando ho usato per la prima volta il threading in C++ ho usato funzioni membro statiche, Poi funzioni dell'amico e infine il Librerie BOOST.Attualmente preferisco BOOST.Negli ultimi anni sono diventato piuttosto un bigotto BOOST.

BOOST sta al C++ come CPAN sta al Perl.:)

La libreria Boost fornisce un meccanismo di copia, che aiuta a trasferire le informazioni degli oggetti nel nuovo thread.Nell'altro esempio di boost boost::bind verrà copiato con un puntatore, anch'esso semplicemente copiato.Quindi dovrai fare attenzione alla validità del tuo oggetto per evitare che il puntatore penzoli.Se implementi operator() e fornisci invece un costruttore di copia e passi l'oggetto direttamente, non devi preoccupartene.

Una soluzione molto migliore, che evita molti problemi:

#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'altro esempio di boost crea l'oggetto thread nell'heap, sebbene non abbia senso farlo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top