将结构对象作为参数传递给线程

passing structure object as parameter to a thread

本文关键字:参数传递 线程 结构 对象      更新时间:2023-10-16

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

我正在传递结构体"&MQStructObj"的地址_beginthreadx的参数,这是我猜的问题

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;
}

你猜对了。

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

动态分配一个与new,并让线程进程delete它。

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

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

或者,通常更可取的是,您可以动态分配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