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

How Can I Exit Thread, When My UI Get Close Input in MFC

我正在用 'MFC' 制作一些程序。

单击按钮时,消息处理程序会创建新的工作线程。

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

在A按钮制作的线程中,它使用的是我制作的C class。

class 动态分配一些工作资源。

按下 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 按钮处理程序中创建事件,然后 post 向 MyCClass 发送消息

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

但是好像不行。 :(

一般机制: 您的工作线程 (WT) 应该有一个受保护的数据成员 bool bRunning = true(默认情况下),一个设置 bRunning = false 的成员函数 Exit()。 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;
}
  • 而不是 new/delete,最好使用 C++ 智能指针。