线程池实现






2.33/5 (6投票s)
2003年4月26日
2分钟阅读

93882

2673
一个简单的线程池。
引言
本文介绍了一个可重用的线程池类。它控制使用的线程数量到一个规定的水平,并将请求调度到线程池中的任何线程执行。
背景
在编写一个包含大量线程的应用程序时,我发现管理大量线程很困难。我认为应该将线程数量限制到一个特定水平,并将任务排队到线程。因此,我决定实现这个可重用的线程池类。
使用代码
- 将 ThreadPool.cpp 和 ThreadPool.h 插入到项目中。
- 项目设置
- 在“项目”菜单上,单击“设置”。
- 在“项目设置”对话框中,单击“C/C++”选项卡。
- 从“类别”下拉列表中选择“代码生成”。
- 从“使用运行时库”下拉列表中选择“多线程”。
- 点击“确定”。
- 调用
Initialize()
并提供所需的线程数;默认值为 1。可以推荐线程和任务的最大数量。如果需要,任务列表的大小将增长。默认值为 24 个线程和 1024 个任务信息。 - 每当需要分配一个任务时,调用
AssignTask()
并提供客户端的_cdecl
函数指针。 - 该函数将由线程池中的任何空闲线程执行。
- 如果需要同步 DATA 成员,则需要在客户端提交的函数中完成同步。
- 当需要增加/减少线程数时,只需再次调用
Initialize
。不会发生资源/内存泄漏。当前线程完成执行后将被中止。 - 要销毁线程池,无需删除线程池对象,请调用
UnInitialize()
。这将删除所有资源。如果线程仍在工作,在发布WM_QUIT
消息并等待一小段时间后,它将终止所有线程。 UnInitialize()
也在析构函数中调用。
在演示应用程序中,使用“工作”菜单将示例任务分配给线程池。
/* S A M P L E - C O D E*/ CMyTestView::CMyTestView() { m_Pool.Initialize(10, /* Required number of threads */ 20, /* Max threads expected; Default = 24*/ 2000 /* Max tasks expected at a time; Default=1024 */); // Now only 10 thread will be in the pool; // Second param 20 is just for internal memory allocation. } void CMyTestView::OnFirstJob() { THREAD_POOL_TASK taskInfo = {TEST_DO_TASK1, DoFirstJob, LPVOID(this)}; m_Pool.AssignTask(&taskInfo ); } // task submitter second void CMyTestView::OnSecondJob() { THREAD_POOL_TASK taskInfo = {TEST_DO_TASK2, DoSecondJob, LPVOID(this)}; m_Pool.AssignTask(&taskInfo ); } // Thread pool call back. - for first task bool DoFirstJob(UINT taskId, LPVOID pData) { CMyTestView *pView = (CMyTestView*)pData; return pView->DoJob(taskId); } // Thread pool call back. - for second task bool DoSecondJob(UINT taskId, LPVOID pData) { CMyTestView *pView = (CMyTestView*)pData; return pView->DoJob(taskId); } // Actual execution goes here. bool CMyTestView::DoJob(UINT taskId) { switch(taskId) { case TEST_DO_TASK1: { m_Message = _T("Doing FIRST job"); Invalidate(0); int nCount = 1; while (nCount--) { Sleep(1000); Beep(100, 1000); } } break; case TEST_DO_TASK2: { m_Message = _T("Doing SECOND job"); Invalidate(0); int nCount = 2; while (nCount--) { Sleep(2000); Beep(200, 2000); } } } return true; } void CMyTestView::OnResetWorkLoad() { m_Message = _T("On Reset Work Load"); Invalidate(0); m_Pool.Initialize(5, /* Required number of threads */ 20, /* Max threads expected; Default = 24*/ 2000 /* Max tasks expected at a time; Default=1024 */); // Now only 5 thread will be in the pool; // Out of previous TEN, FIVE will be removed. }
关注点
我学习了线程池的用处。令人烦恼的是,回调函数需要全局函数。我通过在类中静态函数来管理它。