问题:
使用一个串口类进行串口收发,由于只是调试,所以并没有真实的数据能被接收,所以原来的程序问题多多。
1、没有接收到数据就死循环等待。
2、执行三四个模块(共有18个相似的模块,每个模块发送一帧数据,然后立即接收一帧数据)即崩溃。
但是在调试版本中运行正常。
过程:
第一个问题好解决,等待一定时间(使用一个较大的计数),如果超过一定时间没有收到,则退出(当然,以后可能会有隐患)。
第二个问题不好解决,因为表现并不明显,刚开始也没有锁定是串口收发出现问题。
先是怀疑MFC的DDX_Control太多出现无法预测的问题,未果。
后又怀疑线程同步有问题,使用全局变量进行同步,未果。
大量使用Release崩溃地址进行查找也未果。
后来才发现屏蔽掉串口接收函数就可以成功,于是赶快逐行测试,最后发现只要屏蔽掉WaitCommEvent函数就可以成功。
打开MSDN,发现并没有关于这方面的说明。所以只好怀疑是传进去的变量出了问题。经检查发现OVERLAPPED变量都是临时栈区变量,进行AfxMessageBox显示后,发现崩溃前各个变量地址相同,后来地址出现偏移(向前偏移了12个字节),接着就崩溃了。
于是,将临时栈区变量改为类成员变量,测试后可以通过并成功运行。
总结:
多线程会带来诸多问题:
1、MFC类对象不是线程安全的,所以不定在什么情况下会崩溃。
a、 mfc的大多数类不是线程安全的,cwnd及其消息路由是其中之最。
b、 mfc界面类的大多数方法,最后都是通过sendmessage实现的,而消息处理的
c、cxxxx::fromhandle会根据调用者所在线程查表,如果查不到用户创建的cxxxx
3、启动线程时传输窗口对象(指针?句柄?)容易出现问题。
4、主程序突然退出时容易出现子线程引用对象析构导致崩溃问题。
5、MFC界面包装类(多线程时成员函数调用的断言失败)。
6、也就是说一个线程不可以也不应该访问另一个线程中的包装类对象。
其它参考资料:
MFC多线程编程注意事项http://blog.csdn.net/sunshine1314/article/details/2481602