我想讓Windows線程池(QueueUserWorkItem())調用我的類的成員函數。如何讓Windows線程池調用類成員函數?
不幸的是,這不能通過將成員函數指針作爲參數傳遞給QueueUserWorkItem()來直接完成。
難以做到的是多於一個成員函數必須是可調用的,並且它們具有不同的簽名(儘管這些成員函數都返回void)。
一個可能需要添加幾層抽象才能使這個工作,但我不知道如何處理這個。有任何想法嗎?
我想讓Windows線程池(QueueUserWorkItem())調用我的類的成員函數。如何讓Windows線程池調用類成員函數?
不幸的是,這不能通過將成員函數指針作爲參數傳遞給QueueUserWorkItem()來直接完成。
難以做到的是多於一個成員函數必須是可調用的,並且它們具有不同的簽名(儘管這些成員函數都返回void)。
一個可能需要添加幾層抽象才能使這個工作,但我不知道如何處理這個。有任何想法嗎?
這可能有幫助。 可以使用TR1 ::()函數和tr1 ::綁定到「合併」各種電話:
#include <iostream>
#include <tr1/functional>
using namespace std;
using namespace tr1;
class A
{
public:
void function(int i) { cout << "Called A::function with i=" << i << endl; }
};
void different_function(double c) {
cout << "Called different_function with c=" << c << endl;
}
int main(int argc, char* argv[])
{
function<void()> f = bind(different_function, 3.14165);
f();
A a;
f = bind(&A::function, a, 10);
f();
return 0;
}
函數對象可以作爲一個可調用對象傳遞的地址(僅需要一個地址)。
實施例: 在你的類添加:
char m_FuncToCall;
static DWORD __stdcall myclass::ThreadStartRoutine(LPVOID myclassref)
{
myclass* _val = (myclass*)myclassref;
switch(m_FuncToCall)
{
case 0:
_val->StartMyOperation();
break;
}
return 0;
}
使一個構件,用於將排隊然後
void myclass::AddToQueue(char funcId)
{
m_FuncToCall=funcId;
QueueUserWorkItem(ThreadStartRoutine,this,WT_EXECUTEDEFAULT);
}
或創建
typedef void (*MY_FUNC)(void);
typedef struct _ARGUMENT_TO_PASS
{
myclass* classref;
MY_FUNC func;
}ARGUMENT_TO_PASS;
然後
void myclass::AddToQueue(MY_FUNC func)
{
ARGUMENT_TO_PASS _arg;
_arg.func = func;
_arg.classref = this;
QueueUserWorkItem(ThreadStartRoutine,&_arg,WT_EXECUTEDEFAULT);
}
如果您需要進一步的解釋隨意問:)
編輯:你需要改變ThreadStartRoutine對第二個例子 ,你也可以改變結構來保持傳遞參數
太棒了!正是我需要的。驚人的STL魔術。感謝您向我介紹這一點。現在唯一的問題是線程安全。當線程池嘗試使用它時,函數對象很可能會死亡。我想我需要堆構造函數,但對內存泄漏警惕。關於如何處理這個問題的任何想法? – links77
是的,你需要在堆上構建它。消費線程可以刪除它,但我會建議使用tr1:shared_ptr() –
John