¿Cómo se usa CreateThread()
para crear hilos de funciones que son miembros de la clase?¿Cómo se usa CreateThread para las funciones que son miembros de la clase?
36
A
Respuesta
62
Necesita crear un método estático para utilizar como la función de inicio de subproceso real, y pasar un puntero a la instancia como el argumento lpParameter
a CreateThread
. Eso pasará al método estático, que puede convertirlo en un puntero de objeto y llamar a la función de miembro.
class MyClass
{
static DWORD WINAPI StaticThreadStart(void* Param)
{
MyClass* This = (MyClass*) Param;
return This->ThreadStart();
}
DWORD ThreadStart(void)
{
// Do stuff
}
void startMyThread()
{
DWORD ThreadID;
CreateThread(NULL, 0, StaticThreadStart, (void*) this, 0, &ThreadID);
}
};
9
Otros que se encuentran, pueden querer usar mi solución. Es un archivo fuente completo compilado con VS2008. ¡Vea a continuación un breve ejemplo de instrucciones sobre cómo usar!
// Thread.h
#ifndef __THREAD_H__
#define __THREAD_H__
// #############################################################################
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
// =============================================================================
template<class T>
class Thread
{
// new type Method: pointer to a object's method (this call)
typedef DWORD (T::* Method)(void);
// -----------------------------------------------------------------------------
protected:
HANDLE hThread; // unique handle to the thread
private:
DWORD threadID; // thread id - 0 until started
T* object; // the object which owns the method
Method method; // the method of the object
HANDLE hInterrupt; // mutex to signal an interrupt via ReleaseSemaphore()
HANDLE hSingleStart; // only one thread allowed to call start() mutex
// -----------------------------------------------------------------------------
private:
// This function gets executed by a concurrent thread.
static DWORD run(LPVOID thread_obj)
{
Thread<T>* thread = (Thread<T>*)thread_obj;
return (thread->object->*thread->method)();
}
// Prevent copying of threads: No sensible implementation!
Thread(const Thread<T>& other) {}
// Prevent assignment of threads: No sensible implementation!
Thread<T>& operator =(const Thread<T>& other) {}
// -----------------------------------------------------------------------------
public:
/* Creates a new Thread object. object: the one which method should be
executed. method: pointer to the object's method. */
explicit Thread(T* object, DWORD (T::* method)(void))
{
this->hThread = NULL;
this->object = object;
this->method = method;
this->threadID = 0;
this->hInterrupt = CreateSemaphore(NULL, 1, 1, NULL);
this->hSingleStart = CreateMutex(NULL, FALSE, NULL);
// this->hInterrupt = CreateMutex(NULL, FALSE, NULL);
}
// -----------------------------------------------------------------------------
~Thread(void)
{
if (hInterrupt)
CloseHandle(hInterrupt);
if (hThread)
CloseHandle(hThread);
}
// -----------------------------------------------------------------------------
/* Starts executing the objects method in a concurrent thread. True if the
thread was started successfully; otherwise false. */
bool start()
{
__try {
if (WaitForSingleObject(hSingleStart, 0) != WAIT_OBJECT_0)
return false;
if (hThread) // Thread had been started sometime in the past
{
if (WaitForSingleObject(hThread, 0) == WAIT_TIMEOUT)
{ // if thread's still running deny new start
return false;
}
CloseHandle(hThread);
}
// (Re-)Set not interrupted semaphore state
WaitForSingleObject(hInterrupt, 0);
hThread = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE) Thread<T>::run,
this,
0,
&this->threadID
);
if (hThread)
return true;
return false;
}
__finally
{
ReleaseMutex(hSingleStart);
}
}
// -----------------------------------------------------------------------------
// Blocks the calling thread until this thread has stopped.
inline void join()
{
WaitForSingleObject(hThread, INFINITE);
}
// -----------------------------------------------------------------------------
/* Asks the thread to exit nicely. Thread function must implement checks.
return value indicates if the interrupt could be placed not if the thread
reacts on the interrupt. true indicates success, false an error. */
inline bool interrupt()
{
if (hInterrupt)
{
return ((ReleaseSemaphore(hInterrupt, 1, NULL) == FALSE) ?
false : true);
}
return false;
}
// -----------------------------------------------------------------------------
/* True if an interrupt request was set, otherwise false. */
inline bool isInterrupted()
{
return this->isInterrupted(0);
}
// -----------------------------------------------------------------------------
/* True if an interrupt request was set, otherwise false. Waits for millisec
milliseconds for the interrupt to take place. */
inline bool isInterrupted(DWORD millisec)
{
if (WaitForSingleObject(hInterrupt, millisec) == WAIT_TIMEOUT)
{
return false;
}
ReleaseSemaphore(hInterrupt, 1, NULL); // keep interrupted state
return true;
}
// -----------------------------------------------------------------------------
inline bool isRunning()
{
DWORD exitCode = 0;
if (hThread)
GetExitCodeThread(hThread, &exitCode);
if (exitCode == STILL_ACTIVE)
return true;
return false;
}
// -----------------------------------------------------------------------------
// Getter & Setter
// -----------------------------------------------------------------------------
__declspec(property(get = getThreadHandle)) HANDLE ThreadHandle;
inline HANDLE getThreadHandle()
{
return hThread;
}
// -----------------------------------------------------------------------------
__declspec(property(get = getThreadID)) DWORD ThreadID;
inline DWORD getThreadID()
{
return threadID;
}
// -----------------------------------------------------------------------------
};
// #############################################################################
#endif // __THREAD_H__
ejemplo corto:
// main.cpp
#include <iostream>
#include <string>
#include "Thread.h"
class HelloWorld
{
public:
DWORD print()
{
std::cout << "Hello World!" << std::endl;
return 0;
}
};
int main(void)
{
// Random object with DWORD method (void)
HelloWorld world;
// thread should call print method of world.
Thread<HelloWorld> thread(&world, &HelloWorld::print);
if (thread.start())
std::cout << "Thread start()" << std::endl;
thread.join(); // wait for thread
return 0;
}
Cuestiones relacionadas
- 1. ¿Cómo se evitan las funciones anidadas cuando se usa AJAX?
- 2. ¿Las funciones idempotentes son las mismas que las funciones puras?
- 3. C++ Funciones de miembros vs funciones gratuitas
- 4. especialización de plantillas para funciones de miembros estáticos; ¿cómo?
- 5. Consecuencia de rendimiento de las funciones de miembros volátiles
- 6. las variables globales son nulas cuando se usa PHPUnit
- 7. argumentos múltiples para la función CreateThread
- 8. ¿Cómo probar el método vacío que solo modifica las variables de miembros de la clase privada?
- 9. Los decoradores de Python que forman parte de una clase base no se pueden usar para decorar las funciones de los miembros en las clases heredadas
- 10. ¿Cómo se usa la clase generada en sqoop en MapReduce?
- 11. ¿Qué sucede con los miembros de la clase cuando se usa malloc en lugar de nuevo?
- 12. ¿Por qué el tamaño de clase depende solo de los miembros de datos y no de las funciones de miembros?
- 13. ¿Visibilidad de miembros de la clase?
- 14. ¿Cuáles son las ventajas de las funciones "aplicar"? ¿Cuándo son mejores para usar que "para" bucles, y cuándo no?
- 15. CoffeeScript Miembros de la Clase
- 16. ¿Son costosas las funciones analíticas de Oracle?
- 17. ¿Las funciones de PostgreSQL son transaccionales?
- 18. ¿Declaras que las funciones específicas de tu módulo son estáticas?
- 19. PHP cómo enumerar todas las funciones públicas de la clase
- 20. Vim + OmniCppComplete: Completar en Miembros de clase que son contenedores de STL
- 21. Cuando los bloques son más útiles que las funciones (ruby)?
- 22. ¿Cómo capturo las funciones de Javascript que se están llamando?
- 23. ¿Cómo se usa Moose para agregar funciones convenientes para los atributos de la matriz?
- 24. ¿Cómo se usa una clase SyncAdapter para múltiples autoridades?
- 25. ¿Puede Roxygen ignorar las funciones que no son del usuario?
- 26. Usando 'const' en las funciones de la clase
- 27. Cómo definir las funciones miembro 'final' para una clase
- 28. ¿Los miembros de la clase ocupan memoria?
- 29. Las funciones de JavaScript son objetos?
- 30. _beginthread vs CreateThread