利用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实现的一个简易线程池的更多相关文章

  1. Linux下简易线程池

    线程池简介 线程池是可以用来在后台执行多个任务的线程集合. 这使主线程可以自由地异步执行其他任务.线程池通常用于服务器应用程序. 每个传入请求都将分配给线程池中的一个线程,因此可以异步处理请求,而不会 ...

  2. 基于requests模块的cookie,session和线程池爬取

    目录 基于requests模块的cookie,session和线程池爬取 基于requests模块的cookie操作 基于requests模块的代理操作 基于multiprocessing.dummy ...

  3. 发一个可伸缩线程池大小的python线程池。已通过测试。

    发一个可伸缩线程池大小的线程池. 当任务不多时候,不开那么多线程,当任务多的时候开更多线程.当长时间没任务时候,将线程数量减小到一定数量. java的Threadpoolexcutor可以这样,py的 ...

  4. 基于 getter 和 setter 撸一个简易的MVVM

    Angular 和 Vue 在对Angular的学习中,了解到AngularJS 的两个主要缺点: 对于每一次界面时间,Ajax 或者 timeout,都会进行一个脏检查,而每一次脏检查又会在内部循环 ...

  5. 【转】一个windows线程池实现

    #ifndef _ThreadPool_H_ #define _ThreadPool_H_ #pragma warning(disable: 4530) #pragma warning(disable ...

  6. 用java自制简易线程池(不依赖concurrent包)

    很久之前人们为了继续享用并行化带来的好处而不想使用进程,于是创造出了比进程更轻量级的线程.以linux为例,创建一个进程需要申请新的自己的内存空间,从父进程拷贝一些数据,所以开销是比较大的,线程(或称 ...

  7. 简易线程池Thread Pool

    1. 基本思路 写了个简易的线程池,基本的思路是: 有1个调度线程,负责维护WorkItem队列.管理线程(是否要增加工作线程).调度(把工作项赋给工作线程)等 线程数量随WorkItem的量动态调整 ...

  8. 一个python线程池的源码解析

    python为了方便人们编程高度封装了很多东西,比如进程里的进程池,大大方便了人们编程的效率,但是默认却没有线程池,本人前段时间整理出一个线程池,并进行了简单的解析和注释,本人水平有限,如有错误希望高 ...

  9. 一个自定义线程池的小Demo

    在项目中如果是web请求时候,IIS会自动分配一个线程来进行处理,如果很多个应用程序共享公用一个IIS的时候,线程分配可能会出现一个问题(当然也是我的需求造成的) 之前在做项目的时候,有一个需求,就是 ...

随机推荐

  1. linux反弹shell

    参考链接 http://www.cnblogs.com/r00tgrok/p/reverse_shell_cheatsheet.html http://www.waitalone.cn/linux-s ...

  2. 网站常用js代码搜集

    1.若是手机端打开,则跳转到手机页面 <script language="javascript"> if(navigator.userAgent.match(/(iPh ...

  3. 关于通过addClass与removeClass用jquery控制有良好兼容的CSS3样式

    hi:)好久不见~最近被jquery的animate对某些CSS3特性不兼容搞的头晕眼花,果断百度,阅读了一些高手的博客后突然发现平常很少用到的addClass和removeClass属性居然还可以这 ...

  4. 【Python@Thread】锁示例

    当出现竞态条件时候,即在同一个时刻只有一个线程可以进入临界区,需要使用同步. 常见的同步原语有两种:锁/互斥,信号量. 锁是最简单,最低级的机制. 首先看一个不使用锁时候的多线程示例: from at ...

  5. ckplayer 参数设置详解

    参数   使用说明 f s=0时地为普通的视频地址s=1时是一个网址,网址里存放视频地址s=2时是一个网址,网址里输出xml格式的视频地址s=3时是一个swf文件地址,swf和播放器进行交互读取地址 ...

  6. js禁止浏览器后退,防止重复支付

    <script language="JavaScript"> javascript:window.history.forward(1);</script>

  7. hdu2063 匈牙利算法 二分最大匹配模版题

    过山车 Time Limit: 1000 MS Memory Limit: 32768 KB 64-bit integer IO format: %I64d , %I64u Java class na ...

  8. tab一些 添加 删除 搜索

    tab一些 添加 删除 搜索 案例 <!DOCTYPE html><html lang="en"><head> <meta charset ...

  9. HTTPS科普扫盲帖【转】

    为什么需要https HTTP是明文传输的,也就意味着,介于发送端.接收端中间的任意节点都可以知道你们传输的内容是什么.这些节点可能是路由器.代理等. 举个最常见的例子,用户登陆.用户输入账号,密码, ...

  10. 十二、oracle 数据库(表)的逻辑备份与恢复

    一.介绍逻辑备份是指使用工具export将数据对象的结构和数据导出到文件的过程.逻辑恢复是指当数据库对象被误操作而损坏后使用工具import利用备份的文件把数据对象导入到数据库的过程.物理备份即可在数 ...