基于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的时候,线程分配可能会出现一个问题(当然也是我的需求造成的) 之前在做项目的时候,有一个需求,就是 ...
随机推荐
- win10桌面和手机的扩展API,判断是否有实体后退键API
喜大普奔的win10 uap开发预览版终于出了,这次更新跟8.1的变化不是很大,但是将原本win8.1和wp8.1uap的分项目的形式,改为了整合成一个项目,经过一次编译打包成一个appx包,实现了无 ...
- get与post 获取参数值的方式
get方式 参数带在url后面,form表单中的域 可以 没有value 属性, 后台可以直接在方法的参数中加入和url一样的参数就能直接获得该参数的值(效率高,不安全) post方式 url链接 ...
- Java 集合 HashMap & HashSet 拾遗
Java 集合 HashMap & HashSet 拾遗 @author ixenos 摘要:HashMap内部结构分析 Java HashMap采用的是冲突链表方式 从上图容易看出,如果选择 ...
- JavaScript加减计算方法和显示千分位
Math.formatFloat = function (f, digit) { var m = Math.pow(10, digit); return parseInt(f * m, 10) / m ...
- LeetCode OJ 42. Trapping Rain Water
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- vultr vps官网改版免费注册教程(最新优惠码)
本站强烈推荐的,国外超高性价比vps服务器Vultr官方网站最近更新了,导致一些朋友心生茫然,今天写个简易教程给大家. 首先是打开vultr官网,免费注册一个vultr账号.填写邮箱地址.密码,非常简 ...
- linux命令英文缩写的含义(方便记忆)
命令缩写: ls:list(列出目录内容) cd:Change Directory(改变目录) su:switch user 切换用户 rpm:redhat package manager 红帽子打包 ...
- Python 查找binlog文件
经常需要在 binlog 中查找一些日志信息,于是写了一个简单的脚本.对于非常巨大的 binlog 文件,该脚本可能会速度慢,毕竟还是用的 list,暂时没想到好办法. 详细看代码: #/usr/bi ...
- JPA的介绍
一.JPA概述 1.JPA是什么? JPA:Java Persistence API:用于对象持久化的 API,JPA是Java EE 5.0 平台标准的 ORM 规范, 使得应用程序以统一的方式访问 ...
- [原]创建三个输入文本框,当光标离开文本框的时候如果文本框为空,则将文本框背景色设置为红色,如果不为空则为白色。提示:焦点进入控件的事件是onfocus,焦点离开控件的事件是onblur
window.onload = function () { var txts = document.getElementsByTagName('input'); ...