C++ win32 线程创建线程函数未正确传递参数

C++ win32 thread createThread function not passing parameter correctly

本文关键字:线程 参数 win32 创建 函数 C++      更新时间:2023-10-16

所以,我一直在试图弄清楚 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->m_pIndThreadData。上述data的相同指针将正确传递到SetupThreadFunction中。但是,m_pInd包含空数据,而不是指向预期信息的指针。为什么?

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

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

正确的模式是使用 new 分配对象,填写数据(如果没有通过参数完成 new(,将指针传递给新创建的线程,并让线程在完成对象时delete对象。您在知道线程已经开始之前就delete了对象!

这不是多线程问题;而是指针问题。

这行对我来说没有意义:

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

m_pInd是一个指针,但你用*pInd初始化它,这意味着你想取消引用pInd,但pInd不是指针,更不用说指向指针的指针了。 我看不出这甚至如何编译。

假设你实际上的意思是&而不是*,如:

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

这里的问题是,您正在创建指向堆栈上Individual副本的指针,并且该副本在从构造函数返回时消失,因此您有一个悬而未决的指针。

使用 std::thread。

void ThreadProc(Individual individual);
int main()
{
    Individual individual;
    std::thread thread(ThreadProc, individual);
    thread.join();
    return 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 Threadn";
    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 << "Hin";
    Individual* i = new Individual;
    HANDLE h = SetupThread(i);
    if(h)   
    {
        WaitForSingleObject(h, INFINITE);
        cout << "Donen";
    } else
    {
        cout << "Couldnt create threadn";
    }   
    getchar();
    delete i;
    return 0;
}

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