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

时间:2013-01-15 13:08:57

标签: c++ multithreading

这段代码运行成功,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;
}

2 个答案:

答案 0 :(得分:2)

你猜错了。

您将局部变量的地址传递给thread-proc-startup,然后保留范围(并在进程中销毁对象)。在线程proc中对此对象的引用是在未定义的行为之后。

使用new动态分配一个并让线程proc delete

答案 1 :(得分: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