C ++如何触发PostMessage在另一个线程

时间:2016-04-08 11:17:43

标签: c++ multithreading visual-c++ mfc message-queue

我有一个MFC-C ++应用程序,其中至少有两个线程正在运行" MainFrame" (= GUI线程)和"解算器"线程。

第二个线程(Solver)在某个时刻启动模型的更改,GUI线程应该由PostMessage(...)执行。为了安全起见,我想等待该消息继续在第二个线程中继续。

使用SendMessage(...)求解器线程等待消息执行,但这样我们绕过了不应该成为目标的消息队列。

我的问题:在继续之前,如何正确清理检查/触发我的信息是否已继续?

  1. 我们是否需要检查每个' x'按GetQueueStatus(...)
  2. 计算主线程消息队列的状态
  3. 有没有办法让主线程发回"成功事件"到另一个线程?并且第二个等待事件回来了?
  4. 提升是否为这类问题提供了简单的解决方案?
  5. 是否有类似的问题,我没有找到? (对不起)
  6. 我的功能:

    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; 
    }
    

1 个答案:

答案 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;
}