windows 系统下C++实现的多线程
摘抄http://blog.csdn.net/huyiyang2010/article/details/5809919
Thread.h
#ifndef __THREAD_H__
#define __THREAD_H__ #include <string> #include <windows.h>
#include <process.h> class Runnable
{
public:
virtual ~Runnable() {};
virtual void Run() = ;
}; class CThread : public Runnable
{
private:
explicit CThread(const CThread & rhs); public:
CThread();
CThread(Runnable * pRunnable);
CThread(const char * ThreadName, Runnable * pRunnable = NULL);
CThread(std::string ThreadName, Runnable * pRunnable = NULL);
~CThread(void); /**
开始运行线程
@arg bSuspend 开始运行时是否挂起
**/
bool Start(bool bSuspend = false); /**
运行的线程函数,可以使用派生类重写此函数
**/
virtual void Run(); /**
当前执行此函数线程等待线程结束
@arg timeout 等待超时时间,如果为负数,等待无限时长
**/
void Join(int timeout = -);
/**
恢复挂起的线程
**/
void Resume();
/**
挂起线程
**/
void Suspend();
/**
终止线程的执行
**/
bool Terminate(unsigned long ExitCode); unsigned int GetThreadID();
std::string GetThreadName();
void SetThreadName(std::string ThreadName);
void SetThreadName(const char * ThreadName); private:
static unsigned int WINAPI StaticThreadFunc(void * arg); private:
HANDLE m_handle;
Runnable * const m_pRunnable;
unsigned int m_ThreadID;
std::string m_ThreadName;
volatile bool m_bRun;
}; #endif
Thread.cpp
#include "Thread.h" CThread::CThread(void) :
m_pRunnable(NULL),
m_bRun(false)
{
} CThread::~CThread(void)
{
} CThread::CThread(Runnable * pRunnable) :
m_ThreadName(""),
m_pRunnable(pRunnable),
m_bRun(false)
{
} CThread::CThread(const char * ThreadName, Runnable * pRunnable) :
m_ThreadName(ThreadName),
m_pRunnable(pRunnable),
m_bRun(false)
{
} CThread::CThread(std::string ThreadName, Runnable * pRunnable) :
m_ThreadName(ThreadName),
m_pRunnable(pRunnable),
m_bRun(false)
{
} bool CThread::Start(bool bSuspend)
{
if(m_bRun)
{
return true;
}
if(bSuspend)
{
m_handle = (HANDLE)_beginthreadex(NULL, , StaticThreadFunc, this, CREATE_SUSPENDED, &m_ThreadID);
}
else
{
m_handle = (HANDLE)_beginthreadex(NULL, , StaticThreadFunc, this, , &m_ThreadID);
}
m_bRun = (NULL != m_handle);
return m_bRun;
} void CThread::Run()
{
if(!m_bRun)
{
return;
}
if(NULL != m_pRunnable)
{
m_pRunnable->Run();
}
m_bRun = false;
} void CThread::Join(int timeout)
{
if(NULL == m_handle || !m_bRun)
{
return;
}
if(timeout <= )
{
timeout = INFINITE;
}
::WaitForSingleObject(m_handle, timeout);
} void CThread::Resume()
{
if(NULL == m_handle || !m_bRun)
{
return;
}
::ResumeThread(m_handle);
} void CThread::Suspend()
{
if(NULL == m_handle || !m_bRun)
{
return;
}
::SuspendThread(m_handle);
} bool CThread::Terminate(unsigned long ExitCode)
{
if(NULL == m_handle || !m_bRun)
{
return true;
}
if(::TerminateThread(m_handle, ExitCode))
{
::CloseHandle(m_handle);
return true;
}
return false;
} unsigned int CThread::GetThreadID()
{
return m_ThreadID;
} std::string CThread::GetThreadName()
{
return m_ThreadName;
} void CThread::SetThreadName(std::string ThreadName)
{
m_ThreadName = ThreadName;
} void CThread::SetThreadName(const char * ThreadName)
{
if(NULL == ThreadName)
{
m_ThreadName = "";
}
else
{
m_ThreadName = ThreadName;
}
} unsigned int CThread::StaticThreadFunc(void * arg)
{
CThread * pThread = (CThread *)arg;
pThread->Run();
return ;
}
ThreadPoolExecutor.h
#ifndef __THREAD_POOL_EXECUTOR__
#define __THREAD_POOL_EXECUTOR__ #include "Thread.h"
#include <set>
#include <list>
#include <windows.h> class CThreadPoolExecutor
{
public:
CThreadPoolExecutor(void);
~CThreadPoolExecutor(void); /**
初始化线程池,创建minThreads个线程
**/
bool Init(unsigned int minThreads, unsigned int maxThreads, unsigned int maxPendingTaskse); /**
执行任务,若当前任务列表没有满,将此任务插入到任务列表,返回true
若当前任务列表满了,但当前线程数量小于最大线程数,将创建新线程执行此任务,返回true
若当前任务列表满了,但当前线程数量等于最大线程数,将丢弃此任务,返回false
**/
bool Execute(Runnable * pRunnable); /**
终止线程池,先制止塞入任务,
然后等待直到任务列表为空,
然后设置最小线程数量为0,
等待直到线程数量为空,
清空垃圾堆中的任务
**/
void Terminate(); /**
返回线程池中当前的线程数量
**/
unsigned int GetThreadPoolSize(); private:
/**
获取任务列表中的任务,若任务列表为空,返回NULL
**/
Runnable * GetTask(); static unsigned int WINAPI StaticThreadFunc(void * arg); private:
class CWorker : public CThread
{
public:
CWorker(CThreadPoolExecutor * pThreadPool, Runnable * pFirstTask = NULL);
~CWorker();
void Run(); private:
CThreadPoolExecutor * m_pThreadPool;
Runnable * m_pFirstTask;
volatile bool m_bRun;
}; typedef std::set<CWorker *> ThreadPool;
typedef std::list<Runnable *> Tasks;
typedef Tasks::iterator TasksItr;
typedef ThreadPool::iterator ThreadPoolItr; ThreadPool m_ThreadPool;
ThreadPool m_TrashThread;
Tasks m_Tasks; CRITICAL_SECTION m_csTasksLock;
CRITICAL_SECTION m_csThreadPoolLock; volatile bool m_bRun;
volatile bool m_bEnableInsertTask;
volatile unsigned int m_minThreads;
volatile unsigned int m_maxThreads;
volatile unsigned int m_maxPendingTasks;
}; #endif
ThreadPoolExecutor.cpp
#include "ThreadPoolExecutor.h" CThreadPoolExecutor::CWorker::CWorker(CThreadPoolExecutor * pThreadPool, Runnable * pFirstTask) :
m_pThreadPool(pThreadPool),
m_pFirstTask(pFirstTask),
m_bRun(true)
{ } CThreadPoolExecutor::CWorker::~CWorker()
{
} /**
执行任务的工作线程。
当前没有任务时,
如果当前线程数量大于最小线程数量,减少线程,
否则,执行清理程序,将线程类给释放掉
**/
void CThreadPoolExecutor::CWorker::Run()
{
Runnable * pTask = NULL;
while(m_bRun)
{
if(NULL == m_pFirstTask)
{
pTask = m_pThreadPool->GetTask();
}
else
{
pTask = m_pFirstTask;
m_pFirstTask = NULL;
} if(NULL == pTask)
{
EnterCriticalSection(&(m_pThreadPool->m_csThreadPoolLock));
if(m_pThreadPool->GetThreadPoolSize() > m_pThreadPool->m_minThreads)
{
ThreadPoolItr itr = m_pThreadPool->m_ThreadPool.find(this);
if(itr != m_pThreadPool->m_ThreadPool.end())
{
m_pThreadPool->m_ThreadPool.erase(itr);
m_pThreadPool->m_TrashThread.insert(this);
}
m_bRun = false;
}
else
{
ThreadPoolItr itr = m_pThreadPool->m_TrashThread.begin();
while(itr != m_pThreadPool->m_TrashThread.end())
{
(*itr)->Join();
delete (*itr);
m_pThreadPool->m_TrashThread.erase(itr);
itr = m_pThreadPool->m_TrashThread.begin();
}
}
LeaveCriticalSection(&(m_pThreadPool->m_csThreadPoolLock));
continue;
}
else
{
pTask->Run();
pTask = NULL;
}
}
} ///////////////////////////////////////////////////////////////////////////////////////////// CThreadPoolExecutor::CThreadPoolExecutor(void) :
m_bRun(false),
m_bEnableInsertTask(false)
{
InitializeCriticalSection(&m_csTasksLock);
InitializeCriticalSection(&m_csThreadPoolLock);
} CThreadPoolExecutor::~CThreadPoolExecutor(void)
{
Terminate();
DeleteCriticalSection(&m_csTasksLock);
DeleteCriticalSection(&m_csThreadPoolLock);
} bool CThreadPoolExecutor::Init(unsigned int minThreads, unsigned int maxThreads, unsigned int maxPendingTasks)
{
if(minThreads == )
{
return false;
}
if(maxThreads < minThreads)
{
return false;
}
m_minThreads = minThreads;
m_maxThreads = maxThreads;
m_maxPendingTasks = maxPendingTasks;
unsigned int i = m_ThreadPool.size();
for(; i<minThreads; i++)
{
//创建线程
CWorker * pWorker = new CWorker(this);
if(NULL == pWorker)
{
return false;
}
EnterCriticalSection(&m_csThreadPoolLock);
m_ThreadPool.insert(pWorker);
LeaveCriticalSection(&m_csThreadPoolLock);
pWorker->Start();
}
m_bRun = true;
m_bEnableInsertTask = true;
return true;
} bool CThreadPoolExecutor::Execute(Runnable * pRunnable)
{
if(!m_bEnableInsertTask)
{
return false;
}
if(NULL == pRunnable)
{
return false;
}
if(m_Tasks.size() >= m_maxPendingTasks)
{
if(m_ThreadPool.size() < m_maxThreads)
{
CWorker * pWorker = new CWorker(this, pRunnable);
if(NULL == pWorker)
{
return false;
}
EnterCriticalSection(&m_csThreadPoolLock);
m_ThreadPool.insert(pWorker);
LeaveCriticalSection(&m_csThreadPoolLock);
pWorker->Start();
}
else
{
return false;
}
}
else
{
EnterCriticalSection(&m_csTasksLock);
m_Tasks.push_back(pRunnable);
LeaveCriticalSection(&m_csTasksLock);
}
return true;
} Runnable * CThreadPoolExecutor::GetTask()
{
Runnable * Task = NULL;
EnterCriticalSection(&m_csTasksLock);
if(!m_Tasks.empty())
{
Task = m_Tasks.front();
m_Tasks.pop_front();
}
LeaveCriticalSection(&m_csTasksLock);
return Task;
} unsigned int CThreadPoolExecutor::GetThreadPoolSize()
{
return m_ThreadPool.size();
} void CThreadPoolExecutor::Terminate()
{
m_bEnableInsertTask = false;
while(m_Tasks.size() > )
{
Sleep();
}
m_bRun = false;
m_minThreads = ;
m_maxThreads = ;
m_maxPendingTasks = ;
while(m_ThreadPool.size() > )
{
Sleep();
}
EnterCriticalSection(&m_csThreadPoolLock);
ThreadPoolItr itr = m_TrashThread.begin();
while(itr != m_TrashThread.end())
{
(*itr)->Join();
delete (*itr);
m_TrashThread.erase(itr);
itr = m_TrashThread.begin();
}
LeaveCriticalSection(&m_csThreadPoolLock);
}
main.cpp
#include "Thread.h"
#include "ThreadPoolExecutor.h" class R : public Runnable
{
public:
~R()
{
printf("~R\n");
}
void Run()
{
printf("Hello World\n");
}
}; int main()
{
CThreadPoolExecutor * pExecutor = new CThreadPoolExecutor();
pExecutor->Init(, , );
R r;
for(int i=;i<;i++)
{
while(!pExecutor->Execute(&r))
{
}
}
pExecutor->Terminate();
delete pExecutor;
getchar();
return ;
}
windows 系统下C++实现的多线程的更多相关文章
- 2013-6-2 [转载自CSDN]如何入门Windows系统下驱动开发
[序言]很多人都对驱动开发有兴趣,但往往找不到正确的学习方式.当然这跟驱动开发的本土化资料少有关系.大多学的驱动开发资料都以英文为主,这样让很多驱动初学者很头疼.本人从事驱动开发时间不长也不短,大概 ...
- 如何正确入门Windows系统下驱动开发领域?
[作者]猪头三个人网站 :http://www.x86asm.com/ [序言]很多人都对驱动开发有兴趣,但往往找不到正确的学习方式.当然这跟驱动开发的本土化资料少有关系.大多学的驱动开发资料都以英文 ...
- 如何用python在Windows系统下,生成UNIX格式文件
平时测试工作中,少不了制造测试数据.最近一个项目,我就需要制造一批可在UNIX下正确读取的文件.为确保这批文件能从FTP下载成功,开发叮嘱我:“文件中凡是遇到换行,换行符必须是UNIX下的LF,而不是 ...
- 在Windows系统下用命令把应用程序添加到系统服务
在Windows系统下用命令把应用程序添加到系统服务,使用SC命令. 加入服务格式如下:sc create ServiceName binPath= 程序路径 start= auto(等号后面的空格是 ...
- windows系统下在dos命令行kill掉被占用的pid (转)
原文出自:http://www.2cto.com/os/201304/203771.html windows系统下在dos命令行kill掉被占用的pid 1.开始-->运行-->c ...
- windows系统下简单nodej.s环境配置 安装
国内目前关注最高,维护最好的一个关于nodejs的网站应该是http://www.cnodejs.org/ windows系统下简单nodejs环境配置. 第一步:下载安装文件 下载地址:官网 htt ...
- windows系统下安装MySQL
可以运行在本地windows版本的MySQL数据库程 序自从3.21版以后已经可以从MySQL AB公司获得,而且 MYSQL每日的下载百分比非常大.这部分描述在windows上安装MySQL的过程. ...
- WINDOWS系统下四叶草CLOVER引导U盘制作
一.所需软件1.下载BootDiskUtility链接:http://pan.baidu.com/s/1bwBFyu 密码:glyk 2.下载Clover r3330 USB链接:http://pan ...
- Windows 系统下json 格式的日志文件发送到elasticsearch
Windows 系统下json 格式的日志文件发送到elasticsearch配置 Nxlog-->logstash-->ElasticSearch Logstash https://ww ...
随机推荐
- Netty4 学习笔记之一:客户端与服务端通信 demo
前言 因为以前在项目中使用过Mina框架,感受到了该框架的强大之处.于是在业余时间也学习了一下Netty.因为Netty的主要版本是Netty3和Netty4(Netty5已经被取消了),所以我就直接 ...
- jdk版本切换
安装1.6/1.7/1.8版本的jdk 保存jdk的安装目录下的文件 卸载所有jdk 将jdk各个版本拷贝到一个文件夹下 配置环境变量 因为安装之后系统会有注册表之类的文件,单纯的修改环境是不会修改成 ...
- RG_4
集训前半段马上就要结束了. 很多作业等待着我. 真希望作业君不喜欢我.
- 云 MongoDB 优化让 LBS 服务性能提升十倍
欢迎大家前往腾讯云技术社区,获取更多腾讯海量技术实践干货哦~ 随着国内服务共享化的热潮普及,共享单车,共享雨伞,共享充电宝等各种服务如雨后春笋,随之而来的LBS服务定位问题成为了后端服务的一个挑战.M ...
- Microsoft Visual Studio调试监视器(MSVSMON.EXE)未能启动
在启动VS2010项目时,遇到如图所示"Microsoft Visual Studio调试监视器(MSVSMON.EXE)未能启动"的问题. 原因是VS2010安装路径(我的是D: ...
- 【JVM命令系列】jstat
命令基本概述 Jstat是JDK自带的一个轻量级小工具.全称"Java Virtual Machine statistics monitoring tool",它位于java的bi ...
- HashMap的源码分析(一)
1.hashMap的关键值 DEFAULT_INITIAL_CAPACITY:默认初始容量16,∈(0,1<<30),实际大小为2的整数次幂: DEFAULT_LOAD_FACTOR:默认 ...
- 修改host可以上的一些网站
打开路径 C:\Windows\System32\drivers\etc 博客园 223.6.248.220 www.cnblogs.com github 192.30.253.112 github. ...
- hdu 1542 线段树 求矩形并
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- bzoj3224 普通平衡树(c++vector)
Tyvj 1728 普通平衡树 2014年8月23日6,4365 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有 ...