WriteFile ReadFile 读写串口严重阻塞

时间:2022-03-09 21:38:38
如题:
并不是经常性的 但出现一次就会让程序挂掉
表现为程序进入WriteFile ReadFile两个API函数后就阻塞在那里,阻塞时长4到10秒,甚至直接卡死执行线程。
读串口和写串口都分别在不同的线程中,并有相应的同步机制。
串口使用的是同步模式(即阻塞模式)。

下面是读串口代码
bool CSerialPort::RecvChar(char &cRecved)
{
BOOL  bResult     = TRUE;
DWORD BytesRead   = 0;
if(m_hComm == INVALID_HANDLE_VALUE)
{
return false;
}
EnterCriticalSection(&m_csCommunicationSync);
bResult = ReadFile(m_hComm, &cRecved, 1, &BytesRead, NULL);
if ((!bResult))

DWORD dwError = GetLastError();
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_RXABORT);
LeaveCriticalSection(&m_csCommunicationSync);
return false;
}
LeaveCriticalSection(&m_csCommunicationSync);
return (BytesRead == 1);
}

下面是写串口的代码:
void CSerialPort::WriteData(unsigned char* pData, unsigned int length)
{
BOOL   bResult     = TRUE;
DWORD  BytesToSend = 0;
if(m_hComm == INVALID_HANDLE_VALUE)
{
return ;
}
EnterCriticalSection(&m_csCommunicationSync);
bResult = WriteFile(m_hComm, pData, length, &BytesToSend, NULL);
if (!bResult)  
{
DWORD dwError = GetLastError();
}
PurgeComm(m_hComm, PURGE_TXCLEAR | PURGE_TXABORT);

LeaveCriticalSection(&m_csCommunicationSync);
}

10 个解决方案

#1




读写超时设定为多少?



串行口是全双工设备,可以同时读写,把同步机制去掉试试看!

#2


读写超时为零
最开始不为零 但也是有问题

而且文件资源应该是独占的吧,全双工只是对下面的驱动而言的

#3



你的m_csCommunicationSync好像没有保护什么数据啊?去掉进程同步看一下。
其实这种做法就是把程序尽量瘦身,看看问题究竟在哪里?

#4


使用异步模式可能没有这个问题

#5


我也碰到了,不知道楼主是如何解决 的

#6


串口一直都有数据可以收吗?没有数据的话ReadFile会阻塞啊,你每次收完都PurgeComm清空缓冲区数据了,除非在你调用PurgeComm又有新数据到达,不然绝对要在ReadFile阻塞。

另外你用临界区限制了不能同时读写,一旦ReadFile阻塞了,你的WriteData函数在EnterCriticalSection时肯定就阻塞了,如果你的串口设备要等到你发给它一个数据,才会再给你发数据,那么肯定就死锁了。串口是双工的,收和发不是一条线的,你用不着也不能这样使用临界区。

#7


占楼,看下是怎么解决的,顺道学习下。

#8


   各位大侠,有谁知道我该怎么尽可能快的发送数据么? 我发送的是一条指令,然后等待返回结果,再发送下一条指令。 急  急  急  急  急  急!!!  我改过了波特率,我用的是API ,我用COMSTAT 实例也不行,我该怎么用api实现 它那个ONComm()事件啊,或者其它方法????

#9


我也遇到这样的问题,我用的CSerialPort类,但是如果使用主板自带的串口好像就不会,我用PCI转串口就会在writefile 阻塞,自能重启,求助如何解决!

#10


该回复于2014-08-10 10:03:34被管理员删除

#1




读写超时设定为多少?



串行口是全双工设备,可以同时读写,把同步机制去掉试试看!

#2


读写超时为零
最开始不为零 但也是有问题

而且文件资源应该是独占的吧,全双工只是对下面的驱动而言的

#3



你的m_csCommunicationSync好像没有保护什么数据啊?去掉进程同步看一下。
其实这种做法就是把程序尽量瘦身,看看问题究竟在哪里?

#4


使用异步模式可能没有这个问题

#5


我也碰到了,不知道楼主是如何解决 的

#6


串口一直都有数据可以收吗?没有数据的话ReadFile会阻塞啊,你每次收完都PurgeComm清空缓冲区数据了,除非在你调用PurgeComm又有新数据到达,不然绝对要在ReadFile阻塞。

另外你用临界区限制了不能同时读写,一旦ReadFile阻塞了,你的WriteData函数在EnterCriticalSection时肯定就阻塞了,如果你的串口设备要等到你发给它一个数据,才会再给你发数据,那么肯定就死锁了。串口是双工的,收和发不是一条线的,你用不着也不能这样使用临界区。

#7


占楼,看下是怎么解决的,顺道学习下。

#8


   各位大侠,有谁知道我该怎么尽可能快的发送数据么? 我发送的是一条指令,然后等待返回结果,再发送下一条指令。 急  急  急  急  急  急!!!  我改过了波特率,我用的是API ,我用COMSTAT 实例也不行,我该怎么用api实现 它那个ONComm()事件啊,或者其它方法????

#9


我也遇到这样的问题,我用的CSerialPort类,但是如果使用主板自带的串口好像就不会,我用PCI转串口就会在writefile 阻塞,自能重启,求助如何解决!

#10


该回复于2014-08-10 10:03:34被管理员删除