在并行循环中,有一个关键部分。我尝试在关键部分中使用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();
答案 0 :(得分:1)
让我们说这是问题所在:
void trouble_maker()
{
Sleep(10000);//application stops for 10 seconds
}
您可以使用PostMessage + PeekMessage +模式对话框等待它通过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");
}