【发布时间】:2011-06-09 15:50:47
【问题描述】:
当然,我不能将指向方法的指针传递给 CreateThread 函数。 我该怎么办?
【问题讨论】:
-
谨慎使用 CreateThread,因为它不会为新线程初始化 C(可能还有 C++)运行时。
-
真的吗?如何手动初始化运行时?
标签: c++ windows multithreading winapi pointers
当然,我不能将指向方法的指针传递给 CreateThread 函数。 我该怎么办?
【问题讨论】:
标签: c++ windows multithreading winapi pointers
如果使用一个类,像这样的一些模式通常效果很好:
.h
static UINT __cdecl StaticThreadFunc(LPVOID pParam);
UINT ThreadFunc();
.cpp
// Somewhere you launch the thread
AfxBeginThread(
StaticThreadFunc,
this);
UINT __cdecl CYourClass::StaticThreadFunc(LPVOID pParam)
{
CYourClass *pYourClass = reinterpret_cast<CYourClass*>(pParam);
UINT retCode = pYourClass->ThreadFunc();
return retCode;
}
UINT CYourClass::ThreadFunc()
{
// Do your thing, this thread now has access to all the classes member variables
}
【讨论】:
我经常这样做:
class X {
private:
static unsigned __stdcall ThreadEntry(void* pUserData) {
return ((X*)pUserData)->ThreadMain();
}
unsigned ThreadMain() {
...
}
};
然后我将this 作为用户数据传递给线程创建函数(_beginthread[ex]、CreateThread 等)
【讨论】:
最常见的方法是创建一个具有 run() 方法和 start() 方法的 Thread 类(这些名称是从 Java Thread 类中借用的)。 run() 是一个纯虚函数,您可以在派生自 Thread 的类中重载它以完成实际工作。 start() 方法在内部调用 CreateThread,通过 reinterpret_cast 将 this 指针传递给 void*。 Thread 类还有一个您传递给 CreateThread 的 threadEntryPoint() 静态函数。在 threadEntryPoint() 中,您执行 reinterpret_cast 回 Thread*,然后对其调用 run()。
如果有一种情况,您只想在单独的线程上执行另一个类的方法(无需从 Thread 类继承),您可以创建一个接收一对对象+方法指针的 Thread 派生类在构造函数中,并在 run() 中调用它们。为了让事情变得简单,让这个派生类成为一个模板。还可以查看函子适配器的 boost。
【讨论】:
CreateThread 不会使用指向成员函数的指针。您可以将成员函数包装在静态函数中,该函数通过 lpParameter 获取对象指针。
【讨论】:
CreateThread 的 lpStartAddress 是 DWORD (WINAPI *PTHREAD_START_ROUTINE)(LPVOID lpThreadParameter) 类型,这与成员函数不兼容,因为成员函数在其签名中具有隐式 this 指针。所以创建一个静态函数并将类指针作为参数传递给线程函数。
【讨论】:
如果您在谈论 Native CreateThread 方法,您可能需要执行以下操作
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&MyThreadProc,NULL,NULL,&threadId);
你的回调方法被定义为
void MyThreadProc()
{
}
【讨论】: