最近一段时间我需要在工程中使用串口接收下位机的反馈数据,但是为了防止因为某些未知故障而导致下位机不回传数据从而引起程序死等的情况,我设计了一个5秒钟超时定时器,用来限制最长的等待时间。
我写了一段测试代码,用来模拟工程中的的功能:定义一个超时标志位gb_test,初始化为false,待上位机发送数据之后,启动定时器,然后使用while语句来等待下位机回传反馈数据,如果下位机正常回传,则打断while;如果一直没有回传,则在超时定时器溢出之后,将超时标志位gb_test置为true以打断while,并给出超时提示。
测试代码如下:
void CTestMFCDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
SetTimer(2,5000,NULL);
while(gb_test == false);//等待超时,gb_test为全局变量,初始化为false
MessageBox(_T("超时..."));
gb_test = false;
}
在一个按钮的消息相应程序中,先启动定时器,其中定时器ID为2,定时5000ms,当定时器溢出后,就会进入OnTimer()函数中。此函数中的代码为:
void CTestMFCDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
switch(nIDEvent)
{
case 1:
KillTimer(1);
MessageBox(_T("定时器1"));
break;
case 2:
gb_test=true;
KillTimer(2);
break;
}
CDialog::OnTimer(nIDEvent);
}
它的作用就是将全局变量(超时标志位)gb_test设置为true。
最后的现象是:点击按钮之后,并没有出现理论上的超时提示,而是使得程序没有了响应(通俗地说就是死掉了),这令我百思不得其解。
最后的猜想就是当操作系统执行程序的时候,将while()划分为一个不可分割的进程片段,定时器又是另一个片段,当进入了各自的片段之后,定时器在溢出之后也确实改变了gb_test的值,但是由于这个进程的优先级没有while()的高,无法打断while的执行。
当然,目前这只是结合所学而推测的。我也是接触MFC不久,对操作系统的原理了解不深,欢迎大家批评指正。