基于Win32 SDK实现的一个简易线程池
利用C++实现了一个简易的线程池模型(基于Win32 SDK),方便使用多线程处理任务。共包含Thread.h、Thread.cpp、ThreadPool.h、ThreadPool.cpp四个源文件。功能相对简单,尚待完善。
Thread.h
// Thread.h: interface for the CThread class.
//
////////////////////////////////////////////////////////////////////// #if !defined(AFX_THREAD_H__9BC45342_F764_4104_B614_1CC8A1964171__INCLUDED_)
#define AFX_THREAD_H__9BC45342_F764_4104_B614_1CC8A1964171__INCLUDED_ #if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000 class CThread
{
public:
CThread();
virtual ~CThread(); public:
BOOL IsBusy();
void Terminate();
DWORD GetThreadId() const;
void Run(LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter); protected:
void _SetBusy(BOOL bBusy); private:
void __Proc();
static DWORD WINAPI __ThreadProc(LPVOID lpParameter); protected:
LPTHREAD_START_ROUTINE m_pThreadProc;
LPVOID m_pParameter; BOOL m_bBusy;
CRITICAL_SECTION m_csBusy; HANDLE m_hEventWait;
HANDLE m_hEventExit; HANDLE m_hThread;
DWORD m_dwThreadId;
}; #endif // !defined(AFX_THREAD_H__9BC45342_F764_4104_B614_1CC8A1964171__INCLUDED_)
Thread.cpp
// Thread.cpp: implementation of the CThread class.
//
////////////////////////////////////////////////////////////////////// #include "StdAfx.h"
#include "Thread.h" CThread::CThread()
: m_pThreadProc()
, m_pParameter()
, m_bBusy()
, m_hThread()
{
m_hEventWait = CreateEvent(, TRUE, FALSE, NULL);
m_hEventExit = CreateEvent(, TRUE, FALSE, NULL);
InitializeCriticalSection(&m_csBusy);
m_hThread = CreateThread(, , __ThreadProc, this, , &m_dwThreadId);
} CThread::~CThread()
{
Terminate();
WaitForSingleObject(m_hThread, INFINITE);
CloseHandle(m_hThread);
DeleteCriticalSection(&m_csBusy);
CloseHandle(m_hEventWait);
CloseHandle(m_hEventExit);
} void CThread::Terminate()
{
SetEvent(m_hEventExit);
} BOOL CThread::IsBusy()
{
EnterCriticalSection(&m_csBusy);
BOOL bRet = m_bBusy;
LeaveCriticalSection(&m_csBusy);
return bRet;
} void CThread::_SetBusy(BOOL bBusy)
{
EnterCriticalSection(&m_csBusy);
m_bBusy = bBusy;
LeaveCriticalSection(&m_csBusy);
} DWORD CThread::GetThreadId() const
{
return m_dwThreadId;
} void CThread::Run(LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter)
{
if (!IsBusy() && lpStartAddress)
{
_SetBusy(TRUE);
m_pThreadProc = lpStartAddress;
m_pParameter = lpParameter;
SetEvent(m_hEventWait);
}
} DWORD WINAPI CThread::__ThreadProc(LPVOID lpParameter)
{
CThread* pThis = (CThread*)lpParameter;
pThis->__Proc(); return ;
} void CThread::__Proc()
{
for (;;)
{
if (!m_pThreadProc)
{
HANDLE hEvents[] = {m_hEventExit, m_hEventWait};
DWORD dwRet = WaitForMultipleObjects(, hEvents, FALSE, INFINITE);
if (dwRet - WAIT_OBJECT_0 == ) break;
}
m_pThreadProc(m_pParameter);
m_pThreadProc = NULL;
m_pParameter = NULL;
ResetEvent(m_hEventWait);
_SetBusy(FALSE);
}
}
ThreadPool.h
// ThreadPool.h: interface for the CThreadPool class.
//
////////////////////////////////////////////////////////////////////// #if !defined(AFX_THREADPOOL_H__E24F5439_D623_4511_A874_40CC9417DDEE__INCLUDED_)
#define AFX_THREADPOOL_H__E24F5439_D623_4511_A874_40CC9417DDEE__INCLUDED_ #if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000 #pragma warning(push)
#pragma warning(disable: 4786) #include <queue>
#include <vector>
#include <utility> #pragma warning(pop) class CThread;
class CThreadPool
{
public:
CThreadPool(size_t nMaxCount);
virtual ~CThreadPool(); public:
BOOL IsBusy();
BOOL Wait(DWORD dwMilliseconds);
void Run(LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter); private:
void __Proc();
static DWORD WINAPI __ThreadProc(LPVOID lpParameter); protected:
HANDLE m_hThread;
HANDLE m_hEventExit; CRITICAL_SECTION m_csFunc; std::vector<CThread*> m_vThreads;
std::queue< std::pair<LPTHREAD_START_ROUTINE, LPVOID> > m_qFuncs;
}; #endif // !defined(AFX_THREADPOOL_H__E24F5439_D623_4511_A874_40CC9417DDEE__INCLUDED_)
ThreadPool.cpp
// ThreadPool.cpp: implementation of the CThreadPool class.
//
////////////////////////////////////////////////////////////////////// #include "StdAfx.h"
#include "Thread.h"
#include <algorithm>
#include "ThreadPool.h" CThreadPool::CThreadPool(size_t nMaxCount)
{
for (size_t i(); i < nMaxCount; ++i)
{
m_vThreads.push_back(new CThread);
}
InitializeCriticalSection(&m_csFunc);
m_hEventExit = CreateEvent(NULL, TRUE, FALSE, NULL);
m_hThread = CreateThread(, , __ThreadProc, this, , );
} CThreadPool::~CThreadPool()
{
SetEvent(m_hEventExit);
WaitForSingleObject(m_hThread, INFINITE);
CloseHandle(m_hThread);
for (std::vector<CThread*>::iterator i(m_vThreads.begin())
; i != m_vThreads.end(); ++i)
{
delete *i;
}
m_vThreads.clear();
DeleteCriticalSection(&m_csFunc);
} DWORD WINAPI CThreadPool::__ThreadProc(LPVOID lpParameter)
{
CThreadPool* pThis = (CThreadPool*)lpParameter;
pThis->__Proc(); return ;
} void CThreadPool::__Proc()
{
for (;WaitForSingleObject(m_hEventExit, ) != WAIT_OBJECT_0;)
{
EnterCriticalSection(&m_csFunc);
if (!m_qFuncs.empty())
{
for (std::vector<CThread*>::iterator i(m_vThreads.begin())
; i != m_vThreads.end(); ++i)
{
if (!(*i)->IsBusy() && !m_qFuncs.empty())
{
std::pair<LPTHREAD_START_ROUTINE, LPVOID>& pFunc = m_qFuncs.front();
(*i)->Run(pFunc.first, pFunc.second);
m_qFuncs.pop();
}
}
}
LeaveCriticalSection(&m_csFunc);
}
} void CThreadPool::Run(LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter)
{
EnterCriticalSection(&m_csFunc);
std::pair<LPTHREAD_START_ROUTINE, LPVOID> pFunc(std::make_pair(lpStartAddress, lpParameter));
m_qFuncs.push(pFunc);
LeaveCriticalSection(&m_csFunc);
} BOOL CThreadPool::IsBusy()
{
BOOL bRet(FALSE);
EnterCriticalSection(&m_csFunc);
if (m_qFuncs.empty())
{
for (std::vector<CThread*>::iterator i(m_vThreads.begin())
; i != m_vThreads.end(); ++i)
{
if ((*i)->IsBusy())
{
bRet = TRUE;
break;
}
}
}
else bRet = TRUE;
LeaveCriticalSection(&m_csFunc);
return bRet;
} BOOL CThreadPool::Wait(DWORD dwMilliseconds)
{
DWORD dwTick = GetTickCount();
for (;IsBusy();)
{
Sleep();
if (GetTickCount() - dwTick > dwMilliseconds)
{
break;
}
}
return !IsBusy();
}
使用示例:
// Test.cpp : Defines the entry point for the console application.
// #include "StdAfx.h"
#include "ThreadPool.h" CRITICAL_SECTION cs; using namespace std; DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
EnterCriticalSection(&cs);
cout << LPCSTR(lpParameter) << endl;
LeaveCriticalSection(&cs);
return ;
} int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
InitializeCriticalSection(&cs); CThreadPool *pThrealPool = new CThreadPool();
pThrealPool->Run(ThreadProc, "");
pThrealPool->Run(ThreadProc, "");
pThrealPool->Run(ThreadProc, "");
pThrealPool->Run(ThreadProc, "");
pThrealPool->Run(ThreadProc, "");
pThrealPool->Run(ThreadProc, "");
pThrealPool->Run(ThreadProc, ""); pThrealPool->Wait(INFINIE);
delete pThrealPool; DeleteCriticalSection(&cs); return nRetCode;
}
运行结果:

源代码下载:http://t.cn/RvnJe9S
基于Win32 SDK实现的一个简易线程池的更多相关文章
- Linux下简易线程池
线程池简介 线程池是可以用来在后台执行多个任务的线程集合. 这使主线程可以自由地异步执行其他任务.线程池通常用于服务器应用程序. 每个传入请求都将分配给线程池中的一个线程,因此可以异步处理请求,而不会 ...
- 基于requests模块的cookie,session和线程池爬取
目录 基于requests模块的cookie,session和线程池爬取 基于requests模块的cookie操作 基于requests模块的代理操作 基于multiprocessing.dummy ...
- 发一个可伸缩线程池大小的python线程池。已通过测试。
发一个可伸缩线程池大小的线程池. 当任务不多时候,不开那么多线程,当任务多的时候开更多线程.当长时间没任务时候,将线程数量减小到一定数量. java的Threadpoolexcutor可以这样,py的 ...
- 基于 getter 和 setter 撸一个简易的MVVM
Angular 和 Vue 在对Angular的学习中,了解到AngularJS 的两个主要缺点: 对于每一次界面时间,Ajax 或者 timeout,都会进行一个脏检查,而每一次脏检查又会在内部循环 ...
- 【转】一个windows线程池实现
#ifndef _ThreadPool_H_ #define _ThreadPool_H_ #pragma warning(disable: 4530) #pragma warning(disable ...
- 用java自制简易线程池(不依赖concurrent包)
很久之前人们为了继续享用并行化带来的好处而不想使用进程,于是创造出了比进程更轻量级的线程.以linux为例,创建一个进程需要申请新的自己的内存空间,从父进程拷贝一些数据,所以开销是比较大的,线程(或称 ...
- 简易线程池Thread Pool
1. 基本思路 写了个简易的线程池,基本的思路是: 有1个调度线程,负责维护WorkItem队列.管理线程(是否要增加工作线程).调度(把工作项赋给工作线程)等 线程数量随WorkItem的量动态调整 ...
- 一个python线程池的源码解析
python为了方便人们编程高度封装了很多东西,比如进程里的进程池,大大方便了人们编程的效率,但是默认却没有线程池,本人前段时间整理出一个线程池,并进行了简单的解析和注释,本人水平有限,如有错误希望高 ...
- 一个自定义线程池的小Demo
在项目中如果是web请求时候,IIS会自动分配一个线程来进行处理,如果很多个应用程序共享公用一个IIS的时候,线程分配可能会出现一个问题(当然也是我的需求造成的) 之前在做项目的时候,有一个需求,就是 ...
随机推荐
- WEB前端组件思想【分页】
DEMO1: 很早就想写一些功能性的组件,无奈技术有限一点一点的边工作,边学. 近日工作中用到分页功能,当然由于加快业务进度,第一选择肯定是选择插件,但是实用性来说,还是有那么一点不适合.毕竟插件是通 ...
- MySQL事务内幕与ACID
MySQL的事务实现严格遵循ACID特性,即原子性(atomicity),一致性(consistency),隔离性(isolation),持久性(durability).为了避免一上来就陷入对ACID ...
- MVC中发生System.Data.Entity.Validation.DbEntityValidationException验证异常的解决方法
发生System.Data.Entity.Validation.DbEntityValidationException这个异常的时候,如果没有用特定的异常类去捕捉,是看不到具体信息的. 通常都是用Sy ...
- 理解 Objective-C 的 ARC
英文原文:Understanding Automatic Reference Counting in Objective-C 自动引用计数(Automatic Reference Counting, ...
- javascript动画效果之透明度
在css中的filter对应老版本的ie浏览器,opacity对应的是其他浏览器 <!DOCTYPE html> <html> <head> <meta ch ...
- windows服务-log4net的使用
本文转自http://www.cnblogs.com/puzi0315/archive/2012/08/08/2628966.html Log4net监控服务状态 对于比较复杂的逻辑,可以使用log4 ...
- HIVE 简单总结
hive 1 table 查看 表show tables;查看表结构desc table_name; 2 database 默认 default 创建databasecreate database_n ...
- boost.spirit之解析C++头文件
环境:win7_64旗舰版,VS2008 场景:C++与lua交互是比较繁琐的,当我们编写一个C++类后,如果要给lua使用,就必须写一个lua包装类,将lua与原始C++类关联起来.其实这部分代码编 ...
- GitHub上有很多不错的iOS开源项目
GitHub上有很多不错的iOS开源项目,个人认为不错的,有这么几个:1. ReactiveCocoa:ReactiveCocoa/ReactiveCocoa · GitHub:GitHub自家的函数 ...
- IntelliJ Idea 常用快捷键列表(转)
IntelliJ Idea 常用快捷键列表 Alt+回车 导入包,自动修正Ctrl+N 查找类Ctrl+Shift+N 查找文件Ctrl+Alt+L 格式化代码 Ctrl+Alt+O 优化导 ...