我正在尝试创建一个测试控制台应用程序,它使用不同的线程打开和下载来自不同COM端口的数据。下载数据后,我使用WaitForMutipleObjects()等待从所有线程完成下载。
WaitForMultipleObjects(nThreadCount,m_threadHandle,true,INFINITE);
但这不起作用,线程正在返回而不被执行。这是我的线程功能。
void* Test::GetData(void *p)
{
Test *pThis = (Test *)p;
string strCOMport;
int nChannelNo,nBaudRate;
cout<< " Enter COM port "<<endl;
cin>>strCOMport;
cout<< " Enter Channel Number"<<endl;
cin>>nChannelNo;
cout<< " Enter Baud Rate "<<endl;
cin>>nBaudRate;
if(pThis->InitPort(nChannelNo,0x00,(unsigned char *)strCOMport.c_str(),nBaudRate,0x00) == 0x00)
cout<< "Init port Success"<<endl;
else
{
cout<< "failed";
return NULL;
}
// download
ExitThread(0);
}
这些是分别创建和等待线程的函数
void Test::init()
{
m_threadHandle[nThreadCount] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)GetData,(LPVOID)this,0,&m_dwThreadID[nThreadCount]);
nThreadCount++;
}
void Test::WaitForThreads()
{
WaitForMultipleObjects(nThreadCount,m_threadHandle,true,INFINITE);
}
为什么线程函数突然返回?
答案 0 :(得分:3)
您的线程程序签名错误。请注意,您使用强制转换来编译代码。你的代码最初可能会说:
CreateThread(..., GetData, ...);
编译器反对GetData
说它与LPTHREAD_START_ROUTINE
类型的参数不兼容。不幸的是你选择了错误的解决方将其投放到LPTHREAD_START_ROUTINE
并不会使GetData
成为LPTHREAD_START_ROUTINE
。它只是关闭了编译器。
CreateThread(..., (LPTHREAD_START_ROUTINE)GetData, ...);
在这里,GetData
仍然不是LPTHREAD_START_ROUTINE
,但现在编译器无法将你从自己身上拯救出来。
因此,您需要声明GetData
以获得正确的签名。
DWORD WINAPI GetData(LPVOID lpParameter);
这必须是非成员函数或静态成员函数。
修复所有这些后,您会发现不再需要致电ExitThread()
。您只需从线程函数中编写return 0
即可。