Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将此指针传递给类构造函数中的CreateThread在线程过程中的行为很奇怪_C++_Windows_Multithreading_Constructor_Createthread - Fatal编程技术网

C++ 将此指针传递给类构造函数中的CreateThread在线程过程中的行为很奇怪

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变量时得到的值相

在我的一个类的构造函数中,我调用Windows函数
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
转换为你的类类型?“怪异”是什么意思?你期望什么样的价值观,你看到了什么?