使用线程池的编程模型





5.00/5 (9投票s)
2000年9月21日

150391

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
运算符在堆上生成。 过程结束后,它将自动被框架删除。
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。