多线程下使用CloseHandle关闭串口导致阻塞怎么解决
我在用MFC做一个上位机软件,因为用到串口通信,所以开了一个线程去阻塞读取串口,读取完成之后,通知主线程处理。代码如下:
线程工作函数:
创建线程的代码:
打开串口部分:
工作线程部分:
点击关闭按钮的代码
现在的问题是,我打开串口成功之后,工作线程就阻塞地读取串口。然后我点击关闭按钮,程序卡死。
单步运行时发现,主线程阻塞在CloseHandle上,工作线程阻塞在ReadFile上。
大家有遇到这个问题吗?怎么解决?在线等。。
线程工作函数:
//执行Dlg工作线程
static DWORD WINAPI RunCmcucontrollerDlg_Thread(LPVOID arg)
{
CmcucontrollerDlg *dlg = (CmcucontrollerDlg *)arg;
return dlg->uartWorkThread();
}
创建线程的代码:
//创建信号量
this->readSem = CreateSemaphore(0, 0, 1, 0);
if (this->readSem == NULL)
{
CString str;
DWORD errCode;
errCode = GetLastError();
str.Format(L"创建信号量失败,错误(%d):%s", errCode, GetLastErrorToString(errCode));
::MessageBox(0, str, L"初始化失败", MB_OK);
AfxGetMainWnd()->SendMessage(WM_CLOSE);
return FALSE;
}
//创建工作线程
uartWorkHandle = CreateThread(NULL, 0, RunCmcucontrollerDlg_Thread, (LPVOID)this, 0, &uartWorkThreadId);
if (uartWorkHandle == NULL)
{
CString str;
DWORD errCode;
errCode = GetLastError();
str.Format(L"创建工作线程失败,错误(%d):%s", errCode, GetLastErrorToString(errCode));
::MessageBox(0, str, L"初始化失败", MB_OK);
AfxGetMainWnd()->SendMessage(WM_CLOSE);
}
打开串口部分:
//打开串口
this->uartHandle = CreateFileW(str,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if (!this->uartHandle || this->uartHandle == INVALID_HANDLE_VALUE)
{
this->uartHandle = 0;
errCode = GetLastError();
str.Format(L"串口打开失败,错误(%d):%s", errCode, GetLastErrorToString(errCode));
::MessageBox(0, str, L"打开失败", MB_OK);
return;
}
//设置串口参数
errCode = SetUartParam(this->uartHandle,
baudrate,
dataBits,
parityCheck,
stopBits);
if (errCode)
{
CloseHandle(this->uartHandle);
this->uartHandle = 0;
str.Format(L"串口参数设置失败,错误(%d):%s", errCode, GetLastErrorToString(errCode));
::MessageBox(0, str, L"串口设置失败", MB_OK);
return;
}
//通知线程接收数据
::ReleaseSemaphore(this->readSem, 1, NULL);
工作线程部分:
DWORD CmcucontrollerDlg::uartWorkThread()
{
HWND hwnd = this->GetSafeHwnd();
while (1)
{
WaitForSingleObject(this->readSem, INFINITE);
if (this->uartWorkerTheadExit)
{
break;
}
//读取串口
if (ReadFile(this->uartHandle, this->recvBuffer, sizeof(this->recvBuffer), &this->recvCount, NULL))
{
this->recvError = 0;
}
else
{
this->recvError = GetLastError();
}
//通知主线程
::PostMessage(hwnd, WM_ON_UART_READ, 0, 0);
}
return 0;
}
点击关闭按钮的代码
//关闭串口
if (this->uartHandle)
{
CloseHandle(this->uartHandle);
this->uartHandle = NULL;
openButton->SetWindowTextW(L"打开");
portsBox->EnableWindow(true);
baudrateBox->EnableWindow(true);
dataBitsBox->EnableWindow(true);
parityCheckBox->EnableWindow(true);
stopBitsBox->EnableWindow(true);
dataTimeoutBox->EnableWindow(true);
}
现在的问题是,我打开串口成功之后,工作线程就阻塞地读取串口。然后我点击关闭按钮,程序卡死。
单步运行时发现,主线程阻塞在CloseHandle上,工作线程阻塞在ReadFile上。
大家有遇到这个问题吗?怎么解决?在线等。。
...全文
相关推荐
WIN32 API多线程操作串口代码文档经典教程
WIN32 API多线程操作串口代码文档经典教程,WIN32 API多线程操作串口代码文档经典教程 WIN32 API多线程操作串口代码文档经典教程
VS2010+MFC 使用WinAPI实现串口通信
Win7x64下的MFC中不可调用MSCOMM控件。所以在MFC下使用WinAPI来实现串口通信,亲测可用。
VC打开关闭串口简单源码
演示如果用利用API方法打串口和关闭串口
异步多线程串口通信
VC实现的多线程实现的串口异步通信 VC实现的多线程实现的串口异步通信
借助VC++实现串口通讯程序中的多线程应用.pdf
借助VC++实现串口通讯程序中的多线程应用.pdf


进程/线程/DLL
