1

此代码成功运行,MQStruct 构造函数也初始化了值,我可以在 ExecuteThread 函数中看到,但在 TestFunction 中,我得到了 MQStruct 的垃圾值。

我将 struct "&MQStructObj" 的地址传递给 _beginthreadex 以获取参数,这就是我猜的问题

struct MQStruct {
    MQStruct()
    {
        pointer=NULL;
        serviceName=NULL;
        durability=0;
        msgType=0;
        msgHeader=0;
        msgId=NULL;
        payload=NULL;
        payloadSize=0;
        ttl=0;
        priority=0;
    }

    void* pointer;
    wchar_t *serviceName; 
    int durability; 
    int msgType; 
    int msgHeader; 
    wchar_t *msgId; 
    wchar_t *payload; 
    int payloadSize; 
    int ttl; 
    int priority;
};


int ExecuteThread() {

    HANDLE   heartBeatThread;
    unsigned int hbThreadID;
    int result = 0;

        MQStruct MQStructObj;
        MQStructObj.pointer=this;

    heartBeatThread = (HANDLE)_beginthreadex(NULL, 0 , &TestFunction, &MQStructObj, 0/*CREATE_SUSPENDED*/, &hbThreadID);


    if ( heartBeatThread == 0 )
    {
        result = -1;
        LogEvent(DEBUG_LOG,0, "Fail to create thread");
    }


    CloseHandle(heartBeatThread);

    return result;
}
4

2 回答 2

2

你猜对了。

您将局部变量的地址传递给您的 thread-proc-startup,然后离开作用域(并销毁进程中的对象)。在您的线程过程中对该对象的引用是在未定义的行为之后。

动态分配一个new并让线程处理delete它。

于 2013-01-15T13:11:49.933 回答
2

MQStructObj在堆栈上声明,因此将超出范围并可能在ExecuteThread完成后立即被覆盖。

如果你想在这里使用堆栈对象,你需要添加一些同步来允许你的新线程在返回MQStructObj之前复制。ExecuteThread

或者,通常最好,您可以MQStructObj动态分配并让新线程在空闲时清理它

MQStruct* MQStructObj = new MQStruct();
MQStructObj->pointer=this;
heartBeatThread = (HANDLE)_beginthreadex(NULL, 0 , &TestFunction, MQStructObj, 0, &hbThreadID);
if ( heartBeatThread == 0 ) { // error
    delete MQStructObj;
    result = -1;
}
// ownership of MQStructObj transferred to new thread
于 2013-01-15T13:12:28.873 回答