Me pregunto mejor forma para iniciar un pthread que es miembro de una clase de C++? Mi propio enfoque sigue como una respuesta ...¿La mejor manera de iniciar un hilo como miembro de una clase de C++?
Respuesta
Normalmente utilizo 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.
Tienes que arrancar usando el vacío parámetro *:
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);
Gracias por esto mientras investigo mi pthread actual en C++. Sin embargo, esto no entra en conflicto con la respuesta que se encuentra aquí: http://stackoverflow.com/questions/592160/static-vs-extern-c. ¿No necesita agregar extern "C" de alguna manera? Además, ¿hay algún problema con hacer el trabajo real en el StaticThreadProc? –
Esto puede hacerse simplemente mediante el uso de la biblioteca de impulso, así:
#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 adicionales, estáticos que confunden su interfaz de clase
- Simplemente incluya boost/thread.hpp en el archivo de origen 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 se puede hacer lo mismo pero sin impulso
// 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
Entonces, no me opongo a esto ... pero nadie en la tienda en la que trabajo usa boost ...sería un gran cambio de paradigma. Es una biblioteca bastante grande también ... ¿cuál es la mejor manera de empezar a usarlo? – jdt141
Bueno, en realidad no es una biblioteca, solo un montón de incluye. Así que puedes elegir una pequeña parte que te atraiga y comenzar por incluir esos encabezados donde los necesites. Solo un par de nuevas características del lenguaje que puede usar aquí y allá según lo considere apropiado. – ravenspoint
+1 para impulsar! No es una decisión falsa, pero ¿su variable 'cMyClass theClass' no debería llamarse' cMyClass theObject' ya que no es una clase sino solo una instancia? Creo que esto sería más claro. –
he utilizado tres de los métodos descritos anteriormente. Cuando usé por primera vez el enhebrado en C++ utilicé funciones de miembro estáticas, luego funciones de amigo y finalmente las bibliotecas BOOST. Actualmente prefiero BOOST. En los últimos años me he convertido en el intolerante BOOST.
BOOST es a C++ como CPAN a Perl. :)
La biblioteca de impulso proporciona un mecanismo de copia, que ayuda a transferir la 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 mejor, lo que evita un montón de 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 impulso crea el objeto hilo en el montón, aunque no hay un sentido hacerlo.
¿Qué sucede si hay dos o más métodos diferentes en la clase que necesita ejecutar? Usar el operador() es inteligente (¿lindo?) Pero, ¿es la mejor manera, dado que solo puedes tener uno por clase? – ravenspoint
Otro pensamiento: insistir en copiar la clase cada vez que se inicia el método puede no ser la mejor manera si la copia de clase es costosa (por ejemplo, requiere mucha memoria) o incluso puede romper el diseño si la clase es un singleton. En cualquier caso, lo que está sucediendo tendrá que documentarse con cuidado, ya que está sucediendo mucho más que simplemente ejecutar un método. – ravenspoint
Es una buena idea envolver un mecanismo que le permite llamar a varias funciones de una clase, pero rara vez lo necesitará. Primero pensé que era una buena manera, pero luego noté los efectos secundarios. Si implementa algo con un mecanismo de copia, me gustaría. Pasar el objeto en lugar del puntero al boost :: bind copiará el objeto varias veces. Pero de lo contrario, usted tendrá problemas en la mayoría de los casos, excepto en Singletons y en administración de objetos "locos". – CSpille
- 1. ¿La mejor manera de iniciar una descarga?
- 2. Cómo iniciar la clase de hilo anónimo
- 3. ¿Puede una clase C++ incluirse como miembro?
- 4. Matriz como miembro privado de la clase
- 5. C++ - Inicializando un mapa estático como miembro de clase privada
- 6. Poner un vector C++ como miembro en una clase que usa un grupo de memoria
- 7. ¿Es posible definir un bloque como miembro de una clase?
- 8. mejor manera de enviar un mensaje a un hilo
- 9. decltype (función) como miembro de la clase
- 10. Utilizando una función de miembro de clase C++ como función de devolución de llamada C
- 11. hilo de Java que es mejor manera?
- 12. Almacenamiento de un método como una variable miembro de una clase en C#
- 13. ¿Cuál es la mejor manera de hacer que un hilo indique otro hilo en .NET?
- 14. C# serializar miembro privado de la clase
- 15. Referencia como inicialización de miembro de clase
- 16. Flujo de C++ como variable miembro
- 17. funciones miembro std :: hilo
- 18. La mejor manera de modificar log4j anexado para iniciar sesión
- 19. iOS 4 - Uso de bloques como miembro de una clase
- 20. Cómo iniciar un hilo de IU en C#
- 21. Simulando un miembro estático virtual de una clase en C++?
- 22. ¿La mejor manera de planificar una tarea?
- 23. miembro de referencia como miembros de la clase
- 24. iniciar un temporizador de hilo diferente en C#
- 25. ¿Cuál es la mejor manera de actualizar los controles de formulario de un hilo de trabajo?
- 26. ¿Especifica una función de miembro de clase como amigo de otra clase?
- 27. ¿Hay una manera mejor que #if DebugMode para iniciar sesión
- 28. C++ miembro de la clase puntero a la función global
- 29. Miembro de referencia de clase apunta a otro miembro de la misma clase
- 30. Puntero de función como miembro de una estructura C
La función de envoltura debe tener un enlace C. Los punteros a funciones de funciones libres pueden ser incompatibles debido al enlace de lenguaje – sellibitze