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

使用线程池的编程模型

starIconstarIconstarIconstarIconstarIcon

5.00/5 (9投票s)

2000年9月21日

viewsIcon

150391

downloadIcon

4891

一个管理线程池的类

引言

在很多情况下,我们需要利用多个线程来提高系统性能。每个线程的逻辑几乎相同,但我们需要管理这些线程。如果系统繁忙,我们会创建更多线程;否则,我们会终止一些线程以避免额外的开销。

我做过几个涉及多线程管理的项目。最后,我决定编写一个类来封装这个机制。这个类可以动态分配线程并将作业分配给这些工作线程。您可以派生自己的类,而无需了解处理多线程以及这些线程之间同步的底层机制。但是,您需要使您的工作类线程安全,因为您的对象每次都可能被分配到不同的线程。

我想演示的另一件事是使用IOCompletion端口的功能。我发现它非常容易且有用,特别是当它用作线程之间传输数据的一种方式时。

用法

要使用线程池类,您需要从IWorker派生您的工作类,并从IJobDesc派生您的作业类。处理逻辑必须嵌入在成员函数IWorker::ProcessJob(IJobDesc* pJob)中。 完成后,您可以像这样声明一个线程池

CThreadPool pool;
pool.Start(6, 10);
//do some other jobs here
pool.Stop();

Start函数有两个参数。第一个参数是此线程池对象应生成的最小工作线程数。第二个参数表示此线程池中的最大工作线程数。如果线程池非常忙于处理分配的作业,它将自动生成更多的工作线程。另一方面,当线程池空闲时,一些线程将从池中删除。微调这两个参数以获得最佳性能。

要将作业分配给线程池进行处理,只需调用函数

pool.ProcessJob(pJob, pWorker);

您必须确保您的派生工作类是线程安全的,因为一个工作实例可能同时在多个线程上。您无法控制该过程是否与上次在同一个线程上。

注意

如果处理需要很长时间,当您调用Stop()时,处理可能不会立即完成。 Stop()函数将最多等待2分钟然后返回。此函数有一个可选参数。如果此参数设置为true,该函数无论如何都会终止这些工作线程。如果此参数设置为false,这些工作线程将不会被粗暴地终止并且仍然存在。在这种情况下,您必须注意,调用Stop()后工作对象可能不存在,如果您尝试访问它们,您将收到访问冲突错误。

作业对象必须使用new运算符在堆上生成。 过程结束后,它将自动被框架删除。

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.