65.9K
CodeProject 正在变化。 阅读更多。
Home

C++ 中的高效线程——第 2 部分:ExitableThread 类

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.18/5 (5投票s)

2006年11月22日

2分钟阅读

viewsIcon

25601

downloadIcon

616

将 Win32 线程 API 封装到 C++ 友好的类中。

引言

在过去的几年中,多线程应用程序已成为我开发的主力。我甚至发现自己在不需要的地方编写多线程应用程序。工作线程允许 Win32 应用程序改善用户体验并提高性能。

凭借这种丰富的经验,我总结了一套经常使用的模式(好吧,它们不是经典意义上的模式;更像是范例)。我编写了一些类,可以简化在所有情况下使用这些范例。

在本三篇文章系列的第 2 部分中,我将展示这些范例中最常用的一个:可退出线程范例。大多数工作线程在某种循环中一遍又一遍地执行相同的操作。无论是处理多个不同的文件、将数据从一种格式导出到另一种格式,还是读取通过线路传输的消息,这些操作都有非常特定的节奏。

可退出线程模式的描述

可退出线程模式的基础是将线程与 Win32 事件对象配对。此事件对象在外部事件(用户按下取消按钮、应用程序关闭等)发出信号之前不会发出信号。在工作线程的每次迭代开始或结束时,线程都会检查退出事件。如果设置了该事件,则它会退出循环,执行任何需要的清理。

ExitableThread 类

ExitableThread 类继承自本系列第 1 篇文章中创建的 Thread 类。 这使我们可以利用基本线程创建和方法调用的代码,同时添加退出事件对象和相关方法。

template<class T, class P>
class ExitableThread : public Thread<T, P>
{
public:
    typedef void (T::*ThreadFunc)( P );

    ExitableThread();
    virtual ~ExitableThread();

    // ExitThread methods - Called within the context of an
    // external thread to instruct the embedded (running)
    // thread to exit.  
    //
    // ExitThread() - Signals the event and immediately 
    // returns.  
    //
    // ExitThreadAndWait() - Signals the event and waits 
    // until the thread actually exits or the timeout
    // expires.  Returns true if the thread exited, or
    // false if the timeout expired
    void ExitThread();
    bool ExitThreadAndWait( DWORD timeoutMS = 5000 );

    // IsExitEventSet - Called by the embedded (running)
    // thread to test if the exit event is set.  Returns
    // true if the event has been set, and the thread
    // should exit, and false otherwise
    bool IsExitEventSet();
};

注释说明了代码。新的 ExitThread() 方法允许其他线程等待封装的线程退出。这些方法设置线程的退出事件。ExitThread() 方法设置事件并立即返回到调用者,而 ExitThreadAndWait() 等待线程句柄变为已发出信号。 如果它没有在指定的超时时间过去之前退出,则该线程将被终止。

使用 ExitableThread 类

ExitableThread 类的使用方式与 Thread 父类相同。但是,工作线程的方法应该是一个迭代过程,它会定期调用 IsExitEventSet() 方法以查看是否应该退出。

void TestClass::DoExitableWork( int i )
{
    Files::iterator it;
    for (it = files.begin(); it != files.end(); it++)
    {
        ProcessFile( *it );

        // Check the Exit Event
        if (m_thread.IsExitEventSet())
            break;
    }
}

结论

可退出线程是一种模式(或范例),可帮助控制工作线程及其生命周期。当外部情况需要线程退出时,可退出线程模式允许工作线程获取消息并正确清理并释放任何资源。ExitableThread 类允许在需要迭代工作线程的任何地方轻松插入此模式。

在这个简短系列的最后一部分中,我们将研究如何将 ThreadExitableThread 类扩展为一组强大的类,从而消除对调用者和被调用者的任何假设。

历史

  • 2006.11.22 - 第一次修订。
© . All rights reserved.