template <class Worker, class ThreadTraits = DefaultThreadTraits>
class CThreadPool : public IThreadPoolConfig
符合辅助角色原型的类,提供用于处理线程池上排队的工作项的代码。
ThreadTraits
提供用于在池中创建线程的函数的类。
公共构造函数
在池进行初始化、调整大小或关闭时,池中的线程将被创建和销毁。 Worker 类的实例将在池中每个工作线程的堆栈上创建。 每个实例都将在线程的生命周期内存活。
创建线程后立即调用 Worker::Initialize
将在与该线程关联的对象上调用。 在销毁线程之前,将立即调用 Worker::Terminate
。 这两种方法都必须接受 void
* 参数。 此参数的值通过 CThreadPool::Initialize 的 pvWorkerParam 参数传递到线程池。
当队列和工作线程中有工作项可用于工作时,工作线程将从队列中拉出一个项目并为该线程调用 Worker 对象的 Execute
方法。 然后将三个项目传递给该方法:队列中的项目、传递给 Worker:: 和 Worker:: 的同一个 pvWorkerParam
以及指向 OVERLAPPED 结构(用于 IO 完成端口队列)的指针。Initialize
Terminate
Worker 类通过提供 typedef Worker ::RequestType
来声明将在线程池中排队的项目的类型。 此类型必须能够与 ULONG_PTR 相互转换。
Worker 类的一个示例是 CNonStatelessWorker 类。
继承层次结构
IUnknown
IThreadPoolConfig
CThreadPool
标头:atlutil.h
CThreadPool::AddRef
IUnknown::AddRef
的实现。
ULONG STDMETHODCALLTYPE AddRef() throw();
始终返回 1。
此类不使用引用计数实现生命周期控制。
CThreadPool::CThreadPool
线程池的构造函数。
CThreadPool() throw();
将超时值初始化为 ATLS_DEFAULT_THREADPOOLSHUTDOWNTIMEOUT。 默认时间为 36 秒。 如有必要,你可以在包含 atlutil.h 之前为此符号定义自己的正整数值。
CThreadPool::~CThreadPool
线程池的析构函数。
~CThreadPool() throw();
调用 CThreadPool::Shutdown。
CThreadPool::GetNumThreads
调用此方法可获取池中的线程数。
int GetNumThreads() throw();
返回池中的线程数。
CThreadPool::GetQueueHandle
调用此方法可获取用于对工作项进行排队的 IO 完成端口的句柄。
HANDLE GetQueueHandle() throw();
如果线程池尚未初始化,则返回队列句柄或 NULL。
CThreadPool::GetSize
调用此方法可获取池中的线程数。
HRESULT STDMETHODCALLTYPE GetSize(int* pnNumThreads) throw();
pnNumThreads
[out] 成功时接收池中线程数的变量的地址。
如果成功,则返回 S_OK;否则返回错误 HRESULT。
CThreadPool::GetTimeout
调用此方法可获取线程池等待线程关闭的最长时间(以毫秒为单位)。
HRESULT STDMETHODCALLTYPE GetTimeout(DWORD* pdwMaxWait) throw();
pdwMaxWait
[out] 成功时接收线程池等待线程关闭的最长时间(以毫秒为单位)的变量的地址。
如果成功,则返回 S_OK;否则返回错误 HRESULT。
如果没有向该方法提供其他值,则 CThreadPool::Shutdown 将使用此超时值。
CThreadPool::Initialize
调用此方法可初始化线程池。
HRESULT Initialize(
void* pvWorkerParam = NULL,
int nNumThreads = 0,
DWORD dwStackSize = 0,
HANDLE hCompletion = INVALID_HANDLE_VALUE) throw();
pvWorkerParam
要传递给工作线程对象的 Initialize
、Execute
和 Terminate
方法的工作线程参数。
nNumThreads
池中请求的线程数。
如果 nNumThreads 为负数,则将其绝对值乘以机器中的处理器数即可得到总线程数。
如果 nNumThreads 为零,则 ATLS_DEFAULT_THREADSPERPROC 乘以机器中的处理器数即可获得线程总数。 默认值为每个处理器 2 个线程。 如有必要,你可以在包含 atlutil.h 之前为此符号定义自己的正整数值。
dwStackSize
池中每个线程的堆栈大小。
hCompletion
要与完成端口关联的对象的句柄。
如果成功,则返回 S_OK;否则返回错误 HRESULT。
CThreadPool::QueryInterface
IUnknown::QueryInterface
的实现。
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv) throw();
该类的对象可以成功查询到 IUnknown
和 IThreadPoolConfig 接口。
CThreadPool::QueueRequest
调用此方法可将工作项排队,供池中的线程处理。
BOOL QueueRequest(Worker::RequestType request) throw();
要排队的请求。
如果成功,则返回 TRUE;如果失败,则返回 FALSE。
此方法将工作项添加到队列。 池中的线程按照接收顺序从队列中选取项。
CThreadPool::Release
IUnknown::Release
的实现。
ULONG STDMETHODCALLTYPE Release() throw();
始终返回 1。
此类不使用引用计数实现生命周期控制。
CThreadPool::SetSize
调用此方法可设置池中的线程数。
HRESULT STDMETHODCALLTYPE SetSizeint nNumThreads) throw();
nNumThreads
池中请求的线程数。
如果 nNumThreads 为负数,则将其绝对值乘以机器中的处理器数即可得到总线程数。
如果 nNumThreads 为零,则 ATLS_DEFAULT_THREADSPERPROC 乘以机器中的处理器数即可获得线程总数。 默认值为每个处理器 2 个线程。 如有必要,你可以在包含 atlutil.h 之前为此符号定义自己的正整数值。
如果成功,则返回 S_OK;否则返回错误 HRESULT。
如果指定的线程数小于池中当前的线程数,则对象将关闭放在队列中以由等待线程拾取的消息。 当等待线程从队列中拉取消息时,它会通知线程池并退出线程过程。 此过程会一直重复,直到池中的线程数达到指定数量或直到在 GetTimeout/ SetTimeout 指定的时间段内没有线程退出。 在这种情况下,该方法将返回与WAIT_TIMEOUT对应的 HRESULT,并取消挂起的关闭消息。
CThreadPool::SetTimeout
调用此方法可设置线程池等待线程关闭的最长时间(以毫秒为单位)。
HRESULT STDMETHODCALLTYPE SetTimeout(DWORD dwMaxWait) throw();
dwMaxWait
线程池将等待线程关闭的请求最长时间(以毫秒为单位)。
如果成功,则返回 S_OK;否则返回错误 HRESULT。
超时初始化为 ATLS_DEFAULT_THREADPOOLSHUTDOWNTIMEOUT。 默认时间为 36 秒。 如有必要,你可以在包含 atlutil.h 之前为此符号定义自己的正整数值。
请注意,dwMaxWait 是池等待单个线程关闭的时间。 从池中删除多个线程花费的最长时间可能略小于 dwMaxWait 乘以线程数。
CThreadPool::Shutdown
调用此方法可关闭线程池。
void Shutdown(DWORD dwMaxWait = 0) throw();
dwMaxWait
线程池将等待线程关闭的请求最长时间(以毫秒为单位)。 如果提供 0 或未提供值,此方法将使用 CThreadPool::SetTimeout 设置的超时。
此方法向池中的所有线程发布关闭请求。 如果超时到期,此方法将在任何未退出的线程上调用 TerminateThread。 该方法从类的析构函数中自动调用。
IThreadPoolConfig 接口
DefaultThreadTraits