我想让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