C++ 将此指针传递给类构造函数中的CreateThread在线程过程中的行为很奇怪
在我的一个类的构造函数中,我调用Windows函数C++ 将此指针传递给类构造函数中的CreateThread在线程过程中的行为很奇怪,c++,windows,multithreading,constructor,createthread,C++,Windows,Multithreading,Constructor,Createthread,在我的一个类的构造函数中,我调用Windows函数CreateThread,作为最后一个操作。线程被创建为立即执行,我将类的this指针作为lpParameter传递 在线程过程中,我将传递回类的指针的参数转换为pThis 我可以看到p此指向与调用CreateThread时传递的此指针相同的内存位置。但是,如果我查看pThis->…访问的成员变量,它们的值都是错误的 我希望该指针所属的类中使用的this->member\u变量的值与我在线程过程中写入pThis->member\u变量时得到的值相
CreateThread
,作为最后一个操作。线程被创建为立即执行,我将类的this指针作为lpParameter
传递
在线程过程中,我将传递回类的指针的参数转换为pThis
我可以看到p此
指向与调用CreateThread
时传递的此
指针相同的内存位置。但是,如果我查看pThis->…
访问的成员变量,它们的值都是错误的
我希望该指针所属的类中使用的this->member\u变量的值与我在线程过程中写入pThis->member\u变量时得到的值相同
如果我在另一个成员函数(不是构造函数)中调用CreateThread
,一切都会正常运行
因此,问题是:禁止从C++类的构造函数中调用Windows函数<代码> CREATEINTING <代码>吗?如果是,问题是什么
澄清:
1) 我可以确认该对象始终存在。只有当整个程序结束时,对象才会超出范围。正如我已经说过的:从其他成员函数调用CreateThread
确实有效
2) 更正了“有线”排版,应该是“怪异”,抱歉
一些代码:
我试图发布代码片段,在维护“有故障”的部分的同时,将事情减少到最低限度
class CTimerW32 : public CTimer
{
public:
CTimerW32();
~CTimerW32();
private:
static void CALLBACK TimerCallback(LPVOID lpParam, BOOLEAN bReason);
static DWORD WINAPI WaitCompletition(LPVOID lpParam);
private:
HANDLE m_hCompletitionEvent;
HANDLE m_hCompletitionThread;
bool m_bStartDeferred;
};
您可以安全地忽略基类CTimer
,因为它只是一个抽象基类,支持在不同平台上构建
CTimerW32::CTimerW32()
{
m_bStartDeferred= false;
m_hCompletitionEvent= CreateEvent(NULL, FALSE, FALSE, NULL);
m_hCompletitionThread= CreateThread(NULL, 0, WaitCompletition, this, 0, NULL);
}
在这里,我可以看到调用CreateEvent
后,m_hcompletionevent
是有效的
DWORD WINAPI CTimerW32::WaitCompletition(LPVOID lpParam)
{
CTimerW32* pThis;
DWORD dwRet;
pThis= (CTimerW32*)(lpParam);
while (true) {
// just wait for the completition event to be signaled
dwRet= WaitForSingleObject(pThis->m_hCompletitionEvent, INFINITE);
// ...
if (pThis->m_bStartDeferred) {
// ...
}
}
这里调用WaitForSingleObject
时出现了问题。如前所述,类CTimerW32
(现在pThis
)的对象的this指针在线程创建期间仍然与this指针具有相同的值。然而,pThis->m_hCompletionEvent
中的句柄似乎是随机数据。它不是在构造函数中调用CreateEvent
后观察到的值。在构造函数中创建线程不应该是问题。此外,在运行构造函数中的任何代码来创建线程之前,对象应该由初始值设定项列表完全初始化,因此初始化可能不是问题
很可能您正在监视的对象超出范围,并且在新线程中观察它之前调用了它的析构函数。尝试使用new动态创建对象,看看这是否仍然发生,我打赌不会发生,因为对象在超出范围时不会被破坏
显然,您应该在更高的范围内保留指向此对象的指针,以便最终也可以将其删除:)借助于,您可能会很幸运地调试此问题。如果为程序启用“Basics”选项,它将启用PageHeap,当内存释放时,PageHeap将立即出现故障。如果堆栈分配计时器变量,则运气不太好,但在发现损坏时,应该可以在调试器中看到创建计时器的线程是否仍在声明CTimerW32函数的函数中
最后,对于这个用例,可能比创建自己的专用线程更容易工作,并且资源消耗更少。线程运行时对象是否仍然存在?到那时,它还没有在原始线程中被破坏?你是舒尔吗?当线程工作时,对象一直存在?你能发布一些代码吗:声明pThis
,调用CreateThread
,以及在哪里将pThis
转换为你的类类型?“怪异”是什么意思?你期望什么样的价值观,你看到了什么?