利用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. DapperHelper,SqlHelper

    using System;using System.Collections.Generic;using System.Data.Common;using System.Linq;using Syste ...

  2. get获取Json

    前端代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <sc ...

  3. 【2】Chrome - 快捷键

    记录一下 Chrome 常用的快捷键 温馨提示:点击快捷键回链接到对应的图文 快捷键汇总: 1. Ctrl + [ 或 Ctil + ]  ( Mac: Cmd + [ 或 Cmd + ] ): 移动 ...

  4. GlusterFS缺点分析[转]

    原文:http://blog.sina.com.cn/s/blog_6b89db7a0101gbcy.html GlusterFS(GNU ClusterFile System)是一个开源的分布式文件 ...

  5. jquery收集--php收集所有post数据

    $model = D('Account'); $data = $model->create(); jquery收集数据  sendinvite.serialize() function init ...

  6. Ambari删除服务

    ambari-cassandra-service上面推荐的方法: curl -u admin:$PASSWORD -i -H 'X-Requested-By: ambari' -X PUT -d '{ ...

  7. 文件断点续传原理与实现—— ESFramework 通信框架4.0 进阶(12)

    在ESFramework通信框架 4.0 快速上手(13) -- 文件传送,如此简单一文的详细介绍和ESFramework通信框架 4.0 快速上手(14) -- 聊天系统Demo,增加文件传送功能( ...

  8. [ An Ac a Day ^_^ ] FZU 2030 括号问题 搜索

    FZU一直交不上去 先写在这吧 #include<stdio.h> #include<iostream> #include<algorithm> #include& ...

  9. tomcat 7 启动超时设置。。。实在太隐蔽了

    打开Tomcat,选择 Window->Show View->Servers,在主窗口下的窗口中的Servers标签栏鼠标左键双击tomcat服务器名,例如 Tomcat v7.0 Ser ...

  10. iptables指令参考

    1.首先介绍一下指令和相关配置文件 启动指令:service iptables start 重启指令:service iptables restart 关闭指令:service iptables st ...