MFC 应用程序在 CSingleLock Lock() 后挂起
Posted
技术标签:
【中文标题】MFC 应用程序在 CSingleLock Lock() 后挂起【英文标题】:MFC App hangs after CSingleLock Lock() 【发布时间】:2015-05-13 05:00:37 【问题描述】:void CADAPBatchView::AddMsgToStatusWindow(const CString& strMsg)
CString strTemp;
CString strEngineStatusEntry;
int nLinesToScrollPast = 0;
int nTrimPos = 0;
strEngineStatusEntry.Format(_T("%s %s\n"), CTime::GetCurrentTime().Format( _T( "%H:%M:%S" )), strMsg);
CSingleLock singleLock( &m_csStatusMsg );
singleLock.Lock();
if (m_wndEngineStatusMsgs.GetLineCount() > 200)
m_wndEngineStatusMsgs.SetReadOnly(FALSE); //remove readonly so SetSel will work
m_wndEngineStatusMsgs.SetSel(0, m_wndEngineStatusMsgs.LineIndex(100));
m_wndEngineStatusMsgs.Clear();
m_wndEngineStatusMsgs.SetReadOnly(TRUE); //put back readonly
int nBegin;
nBegin = m_wndEngineStatusMsgs.GetTextLength();
m_wndEngineStatusMsgs.SetSel(nBegin, nBegin); // Select last character
m_wndEngineStatusMsgs.ReplaceSel(strEngineStatusEntry); // Append, move cursor to end of text
//m_wndEngineStatusMsgs.SetSel(-1,0); // Remove Black selection bars
//nBegin = m_wndEngineStatusMsgs.GetTextLength(); // Get New Length
//m_wndEngineStatusMsgs.SetSel(nBegin,nBegin); // Cursor to End of new text
nLinesToScrollPast = m_wndEngineStatusMsgs.GetLineCount() - 9 - m_wndEngineStatusMsgs.GetFirstVisibleLine();
m_wndEngineStatusMsgs.LineScroll( nLinesToScrollPast );
if (m_wndChkStatusMsgLog.GetCheck() == 1)
WriteToLogFile(strEngineStatusEntry);
return;
我附上了显示这两个线程的代码。在转储文件崩溃时,我看到主线程位于singlelock.Lock()
之后的行。第二个线程位于以nLinesToScrollPast
开头的行。我认为发生了死锁情况,但不知道如何。任何帮助表示赞赏,谢谢。
【问题讨论】:
不要附加图片链接,而是复制'n'粘贴重现问题所需的最少代码。 我怀疑所有SetSel
、ReplaceSel
等都在包装SendMessage
,当从工作线程调用时,它将永远等待被阻塞的主线程来处理它们。
首先,你没有附加任何代码,只是一个位图的链接(这在未来将无效,所以这个问题在未来没有意义)。其次,您没有为第二个线程显示任何代码。关于你的死锁:在调试器中启动程序并查看每个线程的调用堆栈,这样你就会明白为什么会出现死锁。
【参考方案1】:
问题是您试图使方法AddMsToStatusWindow
线程安全,以便从其他线程调用它。您的问题是只允许主应用程序线程与 GUI 交互,否则您最终会遇到消息泵问题(因为您确实锁定了SendMessage
)。所以你的设计是错误的。您应该基于CCriticalSection
创建受保护的消息队列。所以线程会将消息放入队列,然后调用PostMessage
通知主线程数据/消息已放入队列。主线程将在消息处理程序中填充此队列中的数据。
【讨论】:
以上是关于MFC 应用程序在 CSingleLock Lock() 后挂起的主要内容,如果未能解决你的问题,请参考以下文章