C ++如何触发PostMessage在另一个线程中进行
C++ How can i trigger that a PostMessage was proceed in another thread
我有一个 MFC-C++ 应用程序,其中至少有两个线程 运行 "MainFrame"(=GUI 线程)和一个 "Solver" 线程。
在某一时刻,第二个线程(求解器)启动了模型的更改,GUI 线程应由 PostMessage(...)
执行。为了安全起见,我想等待该消息在第二个线程中继续。
通过使用 SendMessage(...)
Solver 线程等待消息被执行,但通过这种方式我们绕过了不应该成为目标的消息队列。
我的问题:在我继续之前,如何正确清理check/trigger我的消息已处理?
- 我们是否需要通过
GetQueueStatus(...)
每 'x' 秒检查一次主线程消息队列的状态?
- 有没有办法让主线程发回 "success event" 给另一个线程?第二个等待事件返回?
- boost 是否为此类问题提供了简单的解决方案?
- 是否已经有类似的问题但我没有找到? (抱歉)
我的函数:
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;
}
由于 SendMessage 忽略当前消息队列(它传递队列),我无法使用这种方法。
我在另一个问题中找到了我的解决方案,它是使用 条件变量 和 Mutex 解决的。
我的解决方案:
#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;
}
我有一个 MFC-C++ 应用程序,其中至少有两个线程 运行 "MainFrame"(=GUI 线程)和一个 "Solver" 线程。
在某一时刻,第二个线程(求解器)启动了模型的更改,GUI 线程应由 PostMessage(...)
执行。为了安全起见,我想等待该消息在第二个线程中继续。
通过使用 SendMessage(...)
Solver 线程等待消息被执行,但通过这种方式我们绕过了不应该成为目标的消息队列。
我的问题:在我继续之前,如何正确清理check/trigger我的消息已处理?
- 我们是否需要通过
GetQueueStatus(...)
每 'x' 秒检查一次主线程消息队列的状态? - 有没有办法让主线程发回 "success event" 给另一个线程?第二个等待事件返回?
- boost 是否为此类问题提供了简单的解决方案?
- 是否已经有类似的问题但我没有找到? (抱歉)
我的函数:
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;
}
由于 SendMessage 忽略当前消息队列(它传递队列),我无法使用这种方法。
我在另一个问题中找到了我的解决方案,它是使用 条件变量 和 Mutex 解决的。
我的解决方案:
#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;
}