2013-02-07 126 views
3

如果我有一個成員函數。 。 。創建一個非靜態成員函數的線程?

MyClass::MyFunction() 
{ 
    while(1) 
    { 
     //blah blah blah 
    } 
} 

。 。 。我嘗試創建一個這個函數的線程。 。 。

CreateThread(Null, 0, (LPTHREAD_START_ROUTINE)MyFunction, NULL, 0, NULL); 

。 。 。我總是得到一個錯誤,說(LPTREAD_START_ROUTINE)MyFunction是一個無效的類型轉換,並且我不能創建一個非靜態成員函數的線程。

我不能讓我的功能的靜態因爲我用的是這個指針幾次這需要一個非靜態成員函數來進行。

是否有任何簡單的方法來創建一個非靜態成員函數的線程?

(我在Visual Studio 2010的工作,C++,MFC)

+0

http://stackoverflow.com/questions/6841044/boost-library-and-createthread-win-api – Xyand

+0

本主題在SO上多次報道。 [C++ Thread in member function](http://stackoverflow.com/q/7170269/),[創建線程不接受成員函數](http://stackoverflow.com/q/2891926/),[運行線程(http://stackoverflow.com/q/4666635/)...快速搜索「[線程成員函數](http://stackoverflow.com/search?q=thread+member +功能)「在這個網站上出現很多很多點擊。 –

回答

2

C++成員函數不能稱爲無類的實例。 以下代碼是我的建議之一;

MyClass * instance = ...; // valid instance. 
CreateThread(NULL, 0, StartRoutine, instance, 0, NULL); 

DWORD WINAPI StartRoutine(LPVOID ptr) { 
    static_cast<MyClass*>(ptr)->MyFunction(); 
} 

另一個建議是用static關鍵字聲明成員函數;

class MyClass { 
    ... 
    static DWORD WINAPI MyFunction(); 
    ... 
} 

在第二代碼,MyFunction不能訪問類(非static)成員變量。

+0

這將不起作用,因爲在線程內我使用_this_指針指向窗口。當它到達該行時,我的程序將崩潰。 – xcdemon05

+0

指針'實例'應指向'MyClass'的正確實例。 – kamae

2

創建靜態函數

static DWORD myFunctionCaller(LPVOID* param) 
{ 
    MyClass* myClass = static_cast<MyClass*>(param); 
    myClass->MyFunction(); 
} 

CreateThread(Null, 0, (LPTHREAD_START_ROUTINE)myFunctionCaller, this, 0, NULL); 

的缺點是,你得到一些浮動靜態函數,但是你可以很容易地限制範圍,並應防止您創建的線程太多

+0

爲了避免浮動靜態函數,您還可以將靜態函數定義爲靜態函數。 – mfc

4

你應該隱私所有這些信息,除了可能是「start()」函數。你需要將你的類的私有靜態成員函數作爲操作系統線程啓動的目標,在「start()」中將線程啓動方法傳遞給對象的「this」指針,並將其轉換回對象類型然後在對象本身上調用你的私有主線程方法的靜態函數。由於靜態函數是類的成員,它可以使用私有函數,而如果不是,它不能(不是朋友)。我沒有編譯/測試這個,但是這個想法是:

class MyObj { 
private: 
    void thread() { 
      // this-> is valid here 
    } 

    static DWORD static_entry(LPVOID* param) { 
     MyObj *myObj = (MyObj*)parm; 
     myObj->thread(); 
     return 0; 
    } 

public: 
    void start() { 
     CreateThread(Null, 0, (LPTHREAD_START_ROUTINE)static_entry, this, 0, NULL); 
    } 
}; 

警告之詞:不要在線程運行時銷燬對象!您可能必須與互斥鎖同步,或確保線程在對象銷燬時連接。如果start()的調用者不再管理對象,那麼也可以在thread()的末尾執行「delete this」或在static_entry的末尾刪除myObj。

相關問題