当我的UI在MFC中获得关闭输入时,如何退出线程

时间:2019-04-09 07:28:16

标签: c++ multithreading c++11 stl mfc

我正在使用“ MFC”制作一些程序。

单击A按钮后,消息处理程序将创建新的工作线程。

在工作中,用户可以按B按钮退出应用程序。

在由A按钮创建的线程中,它使用的是我创建的C类。

该类动态分配一些工作资源。

按下B按钮时,我想在我的应用终止之前取消分配资源。

我该怎么做?请帮助!!! :)

void CMyDlg::On_A_BnClicked() {  // do the job button
    ...
    AfxBeginThread(MyThread, (LPVOID)this);
    ...
}
UINT CMyDlg::MyThread(LPVOID arg) {
    ...
    MyCClass mcc;
    for (int i = 0; i < 100; i++) {
        ...
        mcc.init(file_name);
        mcc.do_somethin();
        mcc.deinit();
        ...
    }
    ...
}
void CMyDlg::On_B_BnClicked() {  // close button
}
void MyCClass::init(file_name) {
    mFileClass.Open(file_name, CFile::modeCreate | CFile::modeWrite);
    // and so on
    ...
}

如果在MyThread中执行“ do_somethin”方法时用户按下B按钮。

在MyCClass对象的deinit()方法之后,如何退出MyThread?

我想了一种在B按钮处理程序中创建事件,然后将消息发布到MyCClass的方法

这样我就可以取消初始化MyCClass的消息处理程序中的所有资源。

但是似乎不起作用。 :(

1 个答案:

答案 0 :(得分:0)

一般机制: 您的工作线程(WT)应该具有受保护的数据成员bool bRunning = true(默认情况下),以及设置Exit()的成员函数bRunning = false。 WT循环定期检查bRunning,并在false上中止。创建WT时,请保留其句柄(假设为hWT),并在应用程序退出之前调用hWT->Exit()

-

如果WT可能需要很长时间才能退出,请添加同步机制。举例:

// WT.h

public:

int Run();

void Exit() // ** Assume that only main-thread call this, once. **
{
    std::mutex m_dummy_mutex;
    std::unique_lock<std::mutex> guard(m_dummy_mutex);

    TRACE("WT state switched to not-running.\n");
    m_bRunning = false; // <-- (1)

    TRACE("Wait for WT stopped notification...\n");
    // (It may happen that the receiver wakes up, although no notification happened.)
    bool rv = m_stopped.wait_for(guard, std::chrono::seconds(5), // <-- (2)
               [this]() {return (m_pResource == nullptr); });
               // 'Spurious Wakeup' mitigation with lambda predicate.

    #ifdef _DEBUG
    if (rv)
        TRACE("WT stopped notification - Recieved.\n");
    else
        TRACE("WT stopped notification - Timeout expired.\n");
    #endif
}

protected:

std::condition_variable m_stopped;
bool                    m_bRunning = true; // Running until Stop().
CResource             * m_pResource = nullptr;

在WT循环中:

// WT.cpp

int CWT::Run()
{
    m_pResource = new CResource; // Let's say CResource is your Resource.

    while (m_bRunning)
    {
        // Do something ... (May take time. Check regularly m_bRunning to abort.)

        if (!m_bRunning)
        {
            delete m_pResource;
            m_pResource = nullptr;
            m_stopped.notify_one(); // <-- (3)
            TRACE("WT stopped. Main-thread notified.\n");
            continue;
        }
    }

    return 0;
}
  • 最好使用C ++智能指针来代替new / delete。