C++ &引用;Writefile“;对于使用MFC的RS232通信,将永远挂起,但是
我正在维护一个MFC程序,它可以通过RS232将数据从计算机a发送到计算机B。有时它可以顺利地传输数据,但有时它会永远挂起。有两个线程按顺序向com端口发送相同的数据。第一个线程成功发送数据,但第二个线程挂起在代码“WriteFile”处。当计算机A上的第二个线程挂起在“WriteFile”时,我将一些无意义的数据(如“1”)从计算机B发送回计算机A。然后计算机A上的“WriteFile”挂起停止挂起,计算机B最终看到计算机A上的第二个线程发送的数据 这是你的电话号码 图中显示,计算机A上的两个线程启动自己的测试并将消息发送回计算机B。每个线程几乎同时完成自己的测试并将完成的测试发送给计算机B。但是计算机B只能看到由计算机A上的第一个线程发送的测试(此时第二个线程挂在WriteFile上),直到我从计算机B手动向计算机A发送“1” 这是我从计算机A向计算机B发送消息的代码。cmd的长度是255C++ &引用;Writefile“;对于使用MFC的RS232通信,将永远挂起,但是,c++,mfc,serial-port,writefile,C++,Mfc,Serial Port,Writefile,我正在维护一个MFC程序,它可以通过RS232将数据从计算机a发送到计算机B。有时它可以顺利地传输数据,但有时它会永远挂起。有两个线程按顺序向com端口发送相同的数据。第一个线程成功发送数据,但第二个线程挂起在代码“WriteFile”处。当计算机A上的第二个线程挂起在“WriteFile”时,我将一些无意义的数据(如“1”)从计算机B发送回计算机A。然后计算机A上的“WriteFile”挂起停止挂起,计算机B最终看到计算机A上的第二个线程发送的数据 这是你的电话号码 图中显示,计算机A上的两
BOOL SerialPort::AutoHandlerRES(unsigned char* cmd){
while(wait_transfer.IsLocked())
Sleep(1000);
wait_transfer.Lock();
CString out;
BOOL RetB;
UCHAR EndChar[2]={0x0D,0x0A};
out=CString(cmd);
DWORD num = out.GetLength()+2;
cmd[num-2]=EndChar[0];
cmd[num-1]=EndChar[1];
RetB=WriteFile(this->m_hCom, cmd, num, &num, NULL);
Sleep(1000);
wait_transfer.Unlock();
return RetB;}
我的问题是导致线程B挂起在“WriteFile”的可能原因是什么?为什么悬挂不会发生在一根线上?谢谢大家! 来自:
如果一个线程被阻塞,等待其I/O操作完成,
随后调用通信API的所有其他线程都将
阻止,直到原始操作完成。例如,如果有
线程正在等待ReadFile函数返回,任何其他
发出WriteFile函数的线程将被阻止
您可能会发出阻塞ReadFile
,阻止WriteFile
完成。在您的情况下,这将是线程之间的竞争条件;写入通常在调用读取之前完成,但并不总是这样
防止这种情况发生的最好方法是不要随意调用ReadFile
,而是将其封装在与写入相同的锁中,并在读取之前等待接收COMM事件。原始Win32调用是SetCommMask
和WaitCommEvent
。然后,您可以使用ClearCommError
来检测应该读取多少字节(因为接收事件不会告诉您接收了多少数据)
您还可以使用重叠IO来允许同时IO。我发现它更干净,但并不简单。这可能与您的问题无关,但您使用的锁是错误的。
.Lock()
的要点是在锁未打开时等待;你不必自己等。第二次睡眠也是可疑的。对不起,我没有很好地解释这个功能。该函数将由多个线程调用,所有线程使用相同的RS232 com端口句柄。所以我使用lock来确保线程一次使用WriteFile。这并没有改变我的观点:你用错了。现在我明白了。“.Lock()”具有等待和查看锁是否未打开的两个函数。非常感谢。我应该修改代码,通过检查COMM事件来检查传入的RS232数据,而不是无休止地读取RS232。非常感谢你!