【发布时间】:2016-10-30 13:13:45
【问题描述】:
我正在维护一个 MFC 程序,它可以通过 RS232 将数据从计算机 A 发送到计算机 B。有时它可以顺利传输数据,但有时它会永远挂起。有两个线程按顺序将相同的数据发送到一个 com 端口。第一个线程成功发送数据,但第二个线程在代码“WriteFile”处挂起。当计算机A上的第二个线程挂在“WriteFile”时,我将一些无意义的数据,例如“1”从计算机B发送回计算机A。然后计算机A上的“WriteFile”挂起停止挂起,计算机B终于看到了数据由计算机 A 上的第二个线程发送。
这里是RS232 log from computer B .
图片显示计算机A上的两个线程在那里发起自己的测试并将消息发送回计算机B。每个线程完成自己的测试并几乎同时向计算机B发送TEST_DONE。但是计算机B只能看到计算机A上第一个线程发送的TEST_DONE(此时第二个线程挂在WriteFile上。)直到我手动从计算机B向计算机A发送“1”。
这是我从计算机 A 向计算机 B 发送消息的代码。 cmd 的长度是 255。
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”的可能原因是什么?为什么挂起不会发生在线程 A 上?谢谢!
【问题讨论】:
-
这可能与您的问题无关,但您使用的锁错误。
.Lock()的重点是在锁未打开时等待;你不必等待自己。第二次睡觉也很可疑。 -
对不起,我没有很好地解释函数。该函数将被许多线程调用,并且所有线程都使用相同的 RS232 com 端口句柄。所以我使用锁来确保线程一次使用 WriteFile。
-
这并没有改变我的观点:你用错了。不应该有任何 while() 或 Sleep()。
-
现在我明白了。 “.Lock()”具有等待和查看锁是否未打开的两个功能。谢谢!
标签: c++ mfc serial-port writefile