resueltos resolucion programacion orientada operador objetos hilos ejercicios ejemplos codigo clases ambito c++ pthreads

programacion - operador de resolucion de ambito c++



¿La mejor manera de iniciar un hilo como miembro de una clase de C++? (5)

He usado tres de los métodos descritos anteriormente. La primera vez que utilicé el enhebrado en c ++ utilicé funciones de miembros estáticos , luego funciones de amigos y finalmente las bibliotecas BOOST . Actualmente prefiero BOOST. En los últimos años me he convertido en el intolerante BOOST.

BOOST es para C ++ como CPAN para Perl. :)

Me pregunto cuál es la mejor manera de comenzar un submenú que es miembro de una clase de C ++. Mi propio enfoque sigue como una respuesta ...


Tienes que cargarlo usando el parámetro 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);


Usualmente uso una función miembro estática de la clase, y uso un puntero a la clase como el parámetro void *. Esa función puede realizar el procesamiento de subprocesos o llamar a otra función miembro no estática con la referencia de clase. Esa función puede hacer referencia a todos los miembros de la clase sin una sintaxis incómoda.


La biblioteca de impulso proporciona un mecanismo de copia, que ayuda a transferir información del objeto al nuevo hilo. En el otro ejemplo de boost, boost :: bind se copiará con un puntero, que también se copiará. Por lo tanto, tendrá que cuidar la validez de su objeto para evitar un puntero colgante. Si implementa el operador () y proporciona un constructor de copia en su lugar y pasa el objeto directamente, no tiene que preocuparse por ello.

Una solución mucho más agradable, que evita muchos problemas:

#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

El otro ejemplo de impulso crea el objeto de hilo en el montón, aunque no tiene sentido hacerlo.


Esto se puede hacer simplemente usando la biblioteca de impulso, como esta:

#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

Notas:

  • Esto usa una función de miembro de clase ordinaria. No es necesario agregar miembros extra, estáticos que confunden su interfaz de clase
  • Simplemente incluya boost / thread.hpp en el archivo fuente donde inicia el hilo. Si recién está empezando con el impulso, se puede ignorar todo el resto de ese paquete grande e intimidante.

En C ++ 11 puedes hacer lo mismo pero sin aumentar

// 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