[英]C++ How can i trigger that a PostMessage was proceed in another thread
I have a MFC-C++ application where at least two threads are running "MainFrame" (=GUI thread) and a "Solver" thread. 我有一个MFC-C ++应用程序,其中至少有两个线程正在运行“MainFrame”(= GUI线程)和一个“Solver”线程。
At one point the second thread (Solver) initiate a change in the model which the GUI thread should execute by a PostMessage(...)
. 在某一点上,第二个线程(Solver)启动模型的更改,GUI线程应该由
PostMessage(...)
执行。 To be safe I want to wait that message was proceeded to continue in the second thread. 为了安全起见,我想等待该消息继续在第二个线程中继续。
By using a SendMessage(...)
the Solver thread waits for the message to be executed but in this way we bypass the message queue which shouldn't be the goal. 通过使用
SendMessage(...)
,Solver线程等待消息被执行,但这样我们绕过了不应该成为目标的消息队列。
My question: How can I properly and clean check/trigger that my message was proceed before I continue? 我的问题:在继续之前,我怎样才能正确清理检查/触发我的信息是否继续?
GetQueueStatus(...)
? GetQueueStatus(...)
检查每个'x'秒主线程消息队列的状态? My function: 我的功能:
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;
}
As SendMessage is ignoring the current message queue (it pass the queue) i couldn't use this approach. 由于SendMessage忽略了当前的消息队列(它通过了队列),我无法使用这种方法。
I found my solution in another question where it is solved using a Condition variables and a Mutex . 我在另一个问题中找到了我的解决方案,使用Condition变量和Mutex解决它。 https://stackoverflow.com/a/16909012/5036139
https://stackoverflow.com/a/16909012/5036139
My solution: 我的解决方案
#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;
}
And 和
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.