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

简单的 Worker 线程类

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.07/5 (15投票s)

2009年5月5日

CPOL

2分钟阅读

viewsIcon

41847

downloadIcon

941

一个简单的 Worker 线程类,支持 Join 和线程消息发布

引言

很多时候我们需要创建工作线程,通常我们希望在主线程中等待所有工作线程完成执行,类似于pthreadpthread_join调用。我们希望在工作线程完成时收到通知;检查工作线程的状态,例如它是否仍在线程函数中执行或者已经完成等。有时我们甚至希望在线程函数完成后保持工作线程的存活,以便我们可以重新提交不同的任务(通常在线程池中)。所有这些都可以通过管理事件对象的状态来完成,例如发出信号或未发出信号等。使用不同的事件对象来管理这样的代码是很困难的。我将所有这些常用的工作线程功能整合到了WorkerThread类的基本实现中。

WorkerThread 类

WorkerThread是工作线程的基本实现,具有PostThreadMessageJoinRegisterOnCompleteRoutine和线程执行状态。它可以进一步增强以实现更多其他功能,但我想保持想法的简单性。在这里,我的主要重点是展示如何使用PostThreadMessage来处理工作线程。

Using the Code

在您现有的应用程序中使用WorkerThread类非常简单。您只需要将 *WorkerThread.cpp* 添加到您的项目中,并在您想使用该类的地方包含 *WorkerThread.h*。

在您想要创建工作线程的任何地方添加WorkerThread类的变量。使用Start()创建一个工作线程,可以包含一个可选的自动退出参数(默认为true),要结束线程,请使用End()方法。如果自动退出参数为true,则无需调用WorkerThread类的End()方法。Join()方法会简单地使调用线程等待直到工作线程完成其执行。GetStatus()会告诉你当前的线程状态(NotCreatedCreatedStartedRestartedComplete)。ReExecute()方法只能用于非自动退出线程(在构造函数中使用false参数创建),可以使用不同或相同的数据(这可以进一步增强以避免覆盖数据)。RegisterOnCompleteRoutine()方法可用于注册一个可选的例程,该例程将在线程函数完成后被调用。

以下是展示WorkerThread类用法的示例代码

#include "stdafx.h"
#include "WorkerThread.h"

#define MAXCOUNT 5

DWORD WINAPI ThreadProc(void *param)
{
    int i = (int)param;
    //
    // your code
    //
    
    return 0;
}

DWORD WINAPI OnComplete(void *param)
{
    int i = (int)param;

    printf("OnComplete data = %d\n", i);

    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
    // Create few worker threads with autoQuit false
    WorkerThread workerThread[MAXCOUNT] = {false, false, false, false, false};

    // Register an optional completion routine
    workerThread[2].RegisterOnCompleteRoutine(OnComplete, (void *)1234);

    // Start all of them
    for (int i = 0; i < MAXCOUNT; ++i) {
        if (workerThread[i].Start(ThreadProc, (void *)i)) {
            printf("Started %d\n", i);
        }
    }

    for (int i = 0; i < MAXCOUNT; ++i) {
        if (workerThread[i].ReExecute((void *)i)) {
            printf("Restarted %d\n", i);
        }

    }

    for (int i = 0; i < MAXCOUNT; ++i) {
        workerThread[i].End();
    }

    // main thread will wait here, till all others finish.
    for (int i = 0; i < MAXCOUNT; ++i) {
        workerThread[i].Join();
    }

    return 0;
}        

关注点

请注意在ThreadProc()开始时的虚拟PeekMessage()调用,只是为了强制为我们的工作线程创建一个消息队列。

历史

  • 2009年5月5日:初始版本
© . All rights reserved.