Come utilizzare CreateThread()
per creare thread di funzioni che sono membri della classe?Come usi CreateThread per le funzioni che sono membri della classe?
36
A
risposta
62
È necessario creare un metodo statico da utilizzare come funzione di avvio del thread effettivo e passare un puntatore all'istanza come argomento lpParameter
a CreateThread
. Questo verrà passato al metodo statico, che può lanciarlo su un puntatore a un oggetto e chiamare attraverso la funzione membro.
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
Altri che incontrano, potrebbero voler usare la mia soluzione. È un file di origine completo compilato con VS2008. Vedi sotto per un breve esempio di istruzioni su come usare!
// 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__
esempio 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;
}
Problemi correlati
- 1. È meglio utilizzare le funzioni statiche se non sono necessari membri della classe?
- 2. I membri della classe statici sono bloccati?
- 3. Attributi personalizzati per i membri della classe
- 4. Perché le funzioni in linea sono autorizzate a modificare le variabili dei membri privati?
- 5. Quali sono gli usi delle funzioni virtuali pure in C++?
- 6. Come associare funzioni non membri a una classe in Doxygen?
- 7. Inizializzazione dei membri della classe Non-pointer
- 8. Quali sono alcuni usi interessanti delle funzioni di ordine superiore?
- 9. Javascript classe Ereditarietà per le funzioni
- 10. I membri della classe occupano memoria?
- 11. Namespace e membri della classe statici che collega
- 12. PHP come elencare tutte le funzioni pubbliche della classe
- 13. "Le funzioni sono di prima classe" in swift?
- 14. Chiusure in qualità di membri della classe?
- 15. Proguard mantiene i membri della classe
- 16. Stile Scala: fino a che punto sono nidificate le funzioni?
- 17. i membri della classe ambigua vb.net
- 18. i membri della classe VB.NET pubbliche per default
- 19. I membri di un modello di classe sono istanziati quando viene creata un'istanza della classe?
- 20. i membri della classe statici Python
- 21. Durata dei membri della classe C++
- 22. Inizializzazione membri classe Python
- 23. Come faccio a scorrere i membri della classe?
- 24. ORA-30483: le funzioni della finestra non sono consentite qui
- 25. Le funzioni JavaScript sono asincrone?
- 26. In che modo le funzioni di HoG sono rappresentate graficamente?
- 27. CreateThread vs fork()
- 28. Le funzioni sono chiavi valide per le proprietà dell'oggetto javascript?
- 29. Membri dati classe base virtuale
- 30. Quali sono gli usi del membro get() dalla classe shared_ptr?