临界区中的 DoModal
Posted
技术标签:
【中文标题】临界区中的 DoModal【英文标题】:DoModal in critical section 【发布时间】:2015-03-26 16:39:38 【问题描述】:在并行循环中,有一个临界区。我尝试在关键部分使用 DoModal 执行 mfc 对话框,但是由于主线程等待并行线程,因此我的对话框无法显示和执行。为了打破这种依赖关系,我创建了一个可执行文件并将其作为并行循环中的进程运行。当进程显示对话框并获取信息时。它返回,其他线程继续运行。
但是我的团队领导坚持认为有更好的方法可以做到这一点,但经过数小时的搜索后我无法弄清楚:\
我尝试了一个单独的并行线程。它没有用。 我试过 CWinThread (谷歌说它是 gui 线程 :\ 没有帮助) 我厌倦了创建一个 exe 并运行它。那行得通:)
int someCriticDialog()
#pragma omp critic (showCriticDlg)
CMyDialog ccc;
ccc.DoModal();
/* However the code below works
CreateProcess("someCriticDlg.exe", null, &hProcess);
WaitForSingeObject(hProcess, INFINITE);
*/
#pragma omp parallel
for (int i = 0; i < 5; i++)
someCriticDialog();
【问题讨论】:
【参考方案1】:假设问题出在这里:
void trouble_maker()
Sleep(10000);//application stops for 10 seconds
您可以使用 PostMessage + PeekMessage + modal dialog 通过 GUI 窗口等待它完成:
void PumpWaitingMessages()
MSG msg;
while (::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE))
if (!AfxGetThread()->PumpMessage())
return;
BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
ON_COMMAND(2000, OnDoSomething)
ON_COMMAND(IDCANCEL, OnCancel)
END_MESSAGE_MAP()
CMyDialog::CMyDialog(CWnd* par /*=NULL*/) : CDialog(IDD_DIALOG1, par)
working = false;
stop = false;
BOOL CMyDialog::OnInitDialog()
BOOL res = CDialog::OnInitDialog();
//call the function "OnDoSomething", but don't call it directly
PostMessage(WM_COMMAND, 2000, 0);
return res;
void CMyDialog::OnCancel()
if (working)
stop = true;
else
CDialog::OnCancel();
void CMyDialog::OnDoSomething()
HANDLE h = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&trouble_maker, NULL, 0, NULL);
working = true;
for (;;)
if (WAIT_TIMEOUT != WaitForSingleObject(h, 100)) break;
PumpWaitingMessages();
//update progress bar or something...
if (stop)
//terminate if it's safe
//BOOL res = TerminateThread(h, 0);
//CloseHandle(h);
//CDialog::OnCancel();
//return;
working = false;
MessageBox("done");
【讨论】:
死锁发生在 DoModal 之后。泵消息没有变化。我可能会尝试创建另一个线程来泵送消息,直到有信号停止。 这是有道理的。我的回答完全是垃圾,我改了。 如果我调用 CWinThread->PumpMessage() 甚至在它自己的单独线程中。它会阻塞。 我有一种感觉,您正在从 Dialog 的构造函数或构造函数之前调用某个函数。试试上面的例子,看看你能不能让它工作。不然我不知道你的代码是怎么排列的。以上是关于临界区中的 DoModal的主要内容,如果未能解决你的问题,请参考以下文章