C ++ win32线程createThread函数没有正确传递参数

时间:2015-12-16 23:51:05

标签: c++ multithreading pointers winapi

所以,我一直试图弄清楚c ++多线程是如何工作的,以及如何将它应用到我正在研究的项目中。我试图完成创建一个新线程并在该线程上运行一个函数。我尝试运行的函数名为SetupInfo,并将Individual作为单个参数。我已经看过这个例子,并试图实现它们,但经过多次尝试后,我无法成功地将我需要的参数传递给我希望函数运行的线程。以下是我的想法:

在这里,我创建了一个结构来存储指向稍后我需要的Individual的指针。

struct ThreadData
{
 Individual *m_pInd;
 ThreadData(Individual pInd) : m_pInd(*pInd) {}
};

这里我创建了一个函数,我可以在我的程序中调用它创建运行函数SetupThreadFunction的线程,该函数将void指针作为参数。我试图将变量data传递给此函数,然后将其强制转换回ThreadData以便能够访问结构的项目。

void SetupThread(Individual input)
{
   ThreadData *data = new ThreadData(input);
   CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SetupThreadFunction, data , 0, 0);
   delete data;
}

这里我创建了传递给CreateThread函数的函数,该函数接受一个void指针并将其强制转换为ThreadData,然后理论上可以访问threadData->m_pInd。上面data的相同指针正确传递到SetupThreadFunction。但是,m_pInd包含空数据,而不是指向预期信息的指针。 为什么?

DWORD WINAPI SetupThreadFunction(LPVOID lpParameter)
{
 ThreadData* threadData = (ThreadData*)lpParameter;
 SetupInfo(threadData->m_pInd);
 return 0;
}

有没有更正确的方法将参数传递给我正在创建的新win32线程?

4 个答案:

答案 0 :(得分:4)

这不是一个多线程问题;它是一个指针问题。

这条线对我来说没有意义:

ThreadData(Individual pInd) : m_pInd(*pInd) {}

m_pInd是一个指针,但您正在使用*pInd初始化它,这意味着您要取消引用pInd,但pInd不是指针,让单独指向指针的指针。我不知道这甚至会如何编译。

假设您的确意味着&而不是*,例如:

ThreadData(Individual ind) : m_pInd(&ind) {}

这里的问题是你正在创建一个指向堆栈上Individual副本的指针,并且该副本在从构造函数返回时消失,所以你有一个悬空指针。

答案 1 :(得分:4)

正确的模式是用new分配对象,填入数据(如果没有通过参数到new完成),将指针传递给新创建的线程,然后让线程{I}完成后的对象delete。在知道线程开始之前,你delete了对象!

答案 2 :(得分:1)

使用std::thread

void ThreadProc(Individual individual);

int main()
{
    Individual individual;
    std::thread thread(ThreadProc, individual);
    thread.join();
    return 0;
}

答案 3 :(得分:0)

这是一个简单的代码示例,用于演示已经讨论过的要点。

#include "stdafx.h" // includes <windows.h>, <string> and <iostream>

using std::string;
using std::cout;

class Individual
{
public:
    string s;
};

struct ThreadData
{
    Individual *m_pInd;
    ThreadData(Individual* pInd) : m_pInd(pInd) {}
};

DWORD WINAPI SetupThreadFunction(LPVOID lpParameter)
{
    cout << "Hi From Thread\n";
    ThreadData* threadData = static_cast<ThreadData*>(lpParameter);
    //SetupInfo(threadData->m_pInd);

    // do delete here, once its finished with.
    delete threadData;
    return 0;
}

HANDLE SetupThread(Individual* input)
{
    ThreadData *data = new ThreadData(input);
    return CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SetupThreadFunction, data , 0, 0);   
}

int _tmain(int argc, _TCHAR* argv[])
{
    cout << "Hi\n";
    Individual* i = new Individual;

    HANDLE h = SetupThread(i);

    if(h)   
    {
        WaitForSingleObject(h, INFINITE);
        cout << "Done\n";
    } else
    {
        cout << "Couldnt create thread\n";
    }   

    getchar();

    delete i;

    return 0;
}

请记住,您还可以使用_beginthread作为更简单的界面在Win32上启动线程。