所以,我一直试图弄清楚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线程?
答案 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上启动线程。