我有一个MFC-C ++应用程序,其中至少有两个线程正在运行" MainFrame" (= GUI线程)和"解算器"线程。
第二个线程(Solver)在某个时刻启动模型的更改,GUI线程应该由PostMessage(...)
执行。为了安全起见,我想等待该消息继续在第二个线程中继续。
使用SendMessage(...)
求解器线程等待消息执行,但这样我们绕过了不应该成为目标的消息队列。
我的问题:在继续之前,如何正确清理检查/触发我的信息是否已继续?
GetQueueStatus(...)
?我的功能:
void PostSequencerMessageToGUI(ESequencerSignal signal, CSchedulerStep * step)
{
CMainFrame *mainFrame = theApp.GetMainFrame();
assert(mainFrame);
if (!mainFrame)
return;
mainFrame->PostMessage(WM_SEQUENCER_SIGNAL, signal, reinterpret_cast<LPARAM>(step));
// mainFrame->SendMessage(WM_SEQUENCER_SIGNAL, signal, reinterpret_cast<LPARAM>(step));
// Message was posted, now wait for event back to continue procedure
// ... but how? ...and when to cancel ? ...
return;
}
答案 0 :(得分:0)
由于SendMessage忽略了当前的消息队列(它通过了队列),我无法使用这种方法。
我在另一个问题中找到了我的解决方案,使用条件变量和 Mutex 来解决它。 https://stackoverflow.com/a/16909012/5036139
我的解决方案:
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
boost::condition_variable g_sequencerJobCondition;
boost::mutex g_guiMutex;
void PostSequencerMessageToGUI(ESequencerSignal signal, CSchedulerStep * step)
{
CMainFrame *mainFrame = theApp.GetMainFrame();
assert(mainFrame);
if (!mainFrame)
return;
bool work_is_done = false;
try {
boost::mutex::scoped_lock lock(g_guiMutex);
mainFrame->PostMessage(WM_SEQUENCER_SIGNAL, reinterpret_cast<WPARAM>(&work_is_done), reinterpret_cast<LPARAM>(step));
// Message was posted, now wait for event back to continue procedure
while (!work_is_done){
g_sequencerJobCondition.wait(lock);
}
}
catch (... /*e*/){
// Handle all kind of exception like boost::thread_resource_error, boost::thread_interrupted, boost::exception, std::exception
// ...
}
// ...
return;
}
和
LRESULT CMainFrame::OnSequencerPostMessage( WPARAM wParam, LPARAM lParam )
{
// ...
bool *work_is_done = reinterpret_cast<bool*>(wParam);
CSchedulerStep* step = reinterpret_cast<CSchedulerStep*>(lParam);
// Handle business case ...
// ...
// Finally notify sequencer thread that the work is done
work_is_done = true;
g_sequencerJobCondition.notify_one();
return true;
}