Sınıf üyeleri olan işlevler oluşturmak için CreateThread()
'u nasıl kullanırsınız?Sınıf üyeleri olan işlevler için CreateThread'i nasıl kullanıyorsunuz?
36
A
cevap
62
Geçerli iş parçacığı başlatma işlevi olarak kullanmak için statik bir yöntem oluşturmanız ve örneğebağımsız değişkenini CreateThread
olarak iletmeniz gerekir. Bu, bir nesne işaretçisine dönüştürülebilen ve üye işlevini arayabilen statik yönteme geçecektir.
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
Karşılaştığımız diğerleri, çözümümüzü kullanmak isteyebilir. VS2008 ile derlenmiş eksiksiz bir Kaynak Dosya. Nasıl kullanılacağı hakkında kısa bir talimat örneği için aşağıya bakın!
// 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__
Kısa örnek:
// 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;
}
İlgili konular
- 1. Sınıf üyeleri üzerinde nasıl yineliyorum?
- 2. referanslar ve statik sınıf üyeleri
- 3. Eski API sürümlerinde onaylanmamış işlevler mi kullanıyorsunuz?
- 4. template temel sınıf typedef üyeleri görünmez
- 5. Sınıf üyeleri aracılığıyla bildirimleri sırasına göre yineleyin
- 6. Ruby: MiniTest ile sınıf yöntemini mi kullanıyorsunuz?
- 7. Scala sınıf üyeleri ve yapıcı parametreleri adı çatışması
- 8. Java'da statik verileri depolamak için bir sınıf mı kullanıyorsunuz?
- 9. Yapı üyeleri için şablon işlevi
- 10. Sınıf olarak tanımlanmış aynı türdeki statik constexpr üyeleri (ek ayrıntılar)
- 11. C++ saf sanal işlevler olmadan soyut sınıf?
- 12. “İşlevler birinci sınıf bir tiptir” hızlı mı?
- 13. TypeScript'teki İşlevler için İade Türleri nasıl bildirilir
- 14. Yerel işlevler için Sarıcı
- 15. C# Referanslar; Üyeleri Gizlemek
- 16. C++ - lambda ifadesi, yakalama maddesi ve sınıf üyeleri
- 17. Açısal işlevler için sıkıntı
- 18. Marionette.ItemView modelini kullanmadan görünümler için mi kullanıyorsunuz?
- 19. Dirent yapısının üyeleri
- 20. Python'da "Korumalı" erişim - nasıl? temel sınıf üyeleri yalnızca türetilmiş sınıflar için kapsam olurdu, ama 'genel' değil:
- 21. JQuery aynı sınıf adı olan
- 22. ALTER ROLE tüm üyeleri bırakmak için
- 23. Java'yı nasıl kullanıyorsunuz?
- 24. Sınıf 1 veya sınıf 2 olan öğeyi bulun.
- 25. C: Değişken parametre sayımı olan işlevler için tek bir işlev işaretçisi dizisini nasıl kullanabilirim?
- 26. Bir işlev mi yoksa tip yöntemi mi kullanıyorsunuz?
- 27. Anahtarlar/Değerler C++ 'daki Iteratörler için İşlevler
- 28. Besteci/PSR - İşlevler nasıl yüklenir?
- 29. Hazırda bekletilen üyelerin üyeleri için benzersiz kısıtlamalar
- 30. Örnek üyeleri, C#