主要观点:帮助同事在基于 GUI 的 Windows 应用中添加工作线程,分享线程编程的经验。
关键信息:
- 性能方面:将计算密集型工作转移到工作线程可让主线程更好地服务 GUI 请求。
- 线程库:Windows 有多种线程库,同一应用中使用不同线程库可能导致危险的静默错误。
- 内存栅栏:不同线程可在不同处理器核心,需特殊措施保证变量更新对其他线程可见,如使用
::PostMessage
等。 - GUI 访问:应仅从主线程进行,工作线程可通过
::PostMessage
让主线程执行 GUI 操作,否则可能导致死锁。 - 线程启动:
AfxBeginThread
默认会在不需要时删除线程句柄,若要自己管理可进行相应设置。 - 共享库使用:如 DAO 数据库库,在不同线程中分配和释放可能导致崩溃。
- 初始化:主线程和工作线程在初始化时应调用
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)
和AfxDaoInit()
,完成时调用CoUninitialize()
和AfxDaoTerm()
。 - 线程状态监测:可使用
WaitForSingleObject
监测线程状态,非阻塞或阻塞等待线程完成。 - 竞态条件:是风险,可通过仔细推理避免,有工具可尝试查找但未使用。
重要细节: - 不同编译器家族的线程库(如 GOMP 与 LOMP)有不同的线程运行时,混合使用可能出错。
- 线程启动时隐式执行内存栅栏,保证新线程能正确看到所有内存位置的状态。
- 未在网上找到涵盖所有这些问题的 MFC 线程模型的严格规范。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。