CreatSemaphore.h
#pragma once
#include<windows.h>
class CCreatSemaphore
{
public:
//创建信号量
CCreatSemaphore(
LONG lInitialCount=0, // 信号量初始值
LONG lMaximumCount=1, // 信号量最大值
LPCTSTR lpName=NULL,// 信号量对象名称
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes = NULL // 信号量安全属性
);
~CCreatSemaphore();
//等待信号量,如果信号量>1就返回
int WaitForSingleObject(DWORD dwMilliseconds);
//计算器增加
int ReleaseSemaphore(LONG lReleaseCount);
private:
HANDLE m_hSemaphore;
};
MyCriticalSection.h
#pragma once
#include <windows.h>
class CMyCriticalSection
{
public:
CMyCriticalSection();
~CMyCriticalSection();
int Lock();
int UnLock();
private:
CRITICAL_SECTION m_cs;
};
MyThreadPool.h
#pragma once
#include "CreatSemaphore.h"
#include "MyCriticalSection.h"
#include <list>
using namespace std;
class CWorkItem
{
public:
virtual int Execute() = 0;
};
struct Task
{
int(*pfnFun)(void* pArg);
void* pArg;
};
typedef list<CWorkItem*> TASKLIST;
class CMyThreadPool
{
public:
CMyThreadPool();
~CMyThreadPool();
public:
//创建
int Create(int nMaxThreads);
int Destroy();
int AddTask(CWorkItem* pTask);
private:
CWorkItem* GetTask();
static DWORD WINAPI WorkThread(LPVOID lpParameter);
private:
int m_nCount;//当前线程数量
int m_nIdle;//空闲线程数
int m_nMaxThreads;//最大线程数
TASKLIST m_listTask;//任务列表
CCreatSemaphore m_cSem;//信号量类
CMyCriticalSection m_cCs;//关键段类(锁)
bool m_bQuit;//线程是否退出标志
};
CreatSemaphore.cpp
#include "CreatSemaphore.h"
CCreatSemaphore::CCreatSemaphore(
LONG lInitialCount,
LONG lMaximumCount,
LPCTSTR lpName,
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes
)
{
m_hSemaphore = ::CreateSemaphore(lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName);
}
CCreatSemaphore::~CCreatSemaphore()
{
::CloseHandle(m_hSemaphore);
}
int CCreatSemaphore::WaitForSingleObject(DWORD dwMilliseconds)
{
return ::WaitForSingleObject(m_hSemaphore, dwMilliseconds);
}
int CCreatSemaphore::ReleaseSemaphore(LONG lReleaseCount)
{
return::ReleaseSemaphore(m_hSemaphore, lReleaseCount, NULL);
}
MyCriticalSection.cpp
#include "MyCriticalSection.h"
CMyCriticalSection::CMyCriticalSection()
{
::InitializeCriticalSection(&m_cs);
}
CMyCriticalSection::~CMyCriticalSection()
{
::DeleteCriticalSection(&m_cs);
}
int CMyCriticalSection::Lock()
{
::EnterCriticalSection(&m_cs);
return 0;
}
int CMyCriticalSection::UnLock()
{
::LeaveCriticalSection(&m_cs);
return 0;
}
MyThreadPool.cpp
#include "MyThreadPool.h"
CMyThreadPool::CMyThreadPool() :m_cSem(0, 10000)
{
m_nCount = 0;
m_nIdle = 0;
m_nMaxThreads = 0;
m_bQuit = false;
}
CMyThreadPool::~CMyThreadPool()
{
}
int CMyThreadPool::Create(int nMaxThreads)
{
if (m_bQuit)
{
return 0;
}
m_nMaxThreads = nMaxThreads;
return 0;
}
int CMyThreadPool::Destroy()
{
if (m_bQuit)
{
return 0;
}
m_bQuit = true;
m_cSem.ReleaseSemaphore(m_nCount);
return 0;
}
int CMyThreadPool::AddTask(CWorkItem* pTask)
{
if (m_bQuit)
{
return 0;
}
m_cCs.Lock();
m_listTask.push_back(pTask);
m_cCs.UnLock();
//如果有空闲线程释放信号量让空闲的线程去处理
if (m_nIdle > 0)
{
m_cSem.ReleaseSemaphore(1);
}
else
{
//没有空闲的线程并且线程没有创建到最大数就多创建一个线程工作
if (m_nCount < m_nMaxThreads)
{
::CreateThread(NULL, 0, CMyThreadPool::WorkThread, this, 0, NULL);
m_nCount++;
}
//创建后通知线程工作
m_cSem.ReleaseSemaphore(1);
}
return 0;
}
CWorkItem* CMyThreadPool::GetTask()
{
m_cCs.Lock();
if (m_listTask.empty())
{
m_cCs.UnLock();
return NULL;
}
CWorkItem* pTask = m_listTask.front();
m_listTask.pop_front();
m_cCs.UnLock();
return pTask;
}
DWORD WINAPI CMyThreadPool::WorkThread(LPVOID lpParameter)
{
CMyThreadPool* pThreadPool = (CMyThreadPool*)lpParameter;
printf("WorkThread :%d create\n", ::GetCurrentThreadId());
while (!pThreadPool->m_bQuit)
{
//空闲的线程数量加1
InterlockedIncrement((LPLONG)&pThreadPool->m_nIdle);
printf("WorkThread :%d idle_\n", ::GetCurrentThreadId());
pThreadPool->m_cSem.WaitForSingleObject(INFINITE);
//线程开始工作,空闲数量减一
InterlockedDecrement((LPLONG)&pThreadPool->m_nIdle);
while (!pThreadPool->m_bQuit)
{
CWorkItem* pTask = pThreadPool->GetTask();
if (pTask == NULL)
{
break;
}
pTask->Execute();
delete pTask;
}
}
printf("WorkThread :%d destroy\n", ::GetCurrentThreadId());
return 0;
}
main.cpp
#include "MyThreadPool.h"
#include <stdlib.h>
//
class CWorkItem1 :public CWorkItem
{
public:
virtual int Execute()
{
printf("WorkItem1 id:%d\n", ::GetCurrentThreadId());
return 0;
}
};
class CWorkItem2 :public CWorkItem
{
public:
virtual int Execute()
{
printf("WorkItem2 id:%d\n", ::GetCurrentThreadId());
return 0;
}
};
int main()
{
CMyThreadPool cPool;
SYSTEM_INFO stInfo;
//获取系统核心数,根据系统核心数创建最大线程数量
::GetSystemInfo(&stInfo);
cPool.Create(stInfo.dwNumberOfProcessors * 2);
//添加任务的时候通知线程工作,也是生产者+消费者模型
for (int i = 0; i < 100; ++i)
{
cPool.AddTask(new CWorkItem1());
}
for (int i = 0; i < 100; ++i)
{
cPool.AddTask(new CWorkItem2());
}
//cPool.Destroy();
system("pause");
return 0;
}