今天介紹一下C++11 裡有關線程以及線程池的創建和使用。
在沒有C++11 之前,線程池的編寫,都比較臃腫。該篇文章用到C++11的新特性,代碼更加簡潔和方便,也更加安全。
話不多說 直接看代碼:
ThreadPool.h
<code>#pragma once
// 處理類
class CTask
{
//....
}
class CThreadPool
{
public:
\t\tCThreadPool() = default;
\t\t\tCThreadPool(int iThreadSize);
~CThreadPool();
\t\t CThreadPool(CThreadPool&)= delete;
CThreadPool operator=(const CThreadPool&) = delete;
void CreateThread();
\t\t\tstatic void ThreadWork(PVOID lpParam);
\t\t\tvoid HandleTask(CTask* p);
\t\t\tvoid AddTask(CTask* p);
\t\t\tint GetThreadCount() { return m_threads.size()}
\t\t\tvoid SetThreadCount(int iCount);
\t\t\tint GetIdleThreadCount(){ return m_iIdleCount}
\t\t\tvoid StopThreadPool() {m_bStop.stor(true)}
}
private:
\t\t\tint m_iThreadCount;
\t\t\tint m_iIdleCount = 0;
\t\t\tstd::vector<:thread> m_threads;\t\t// 線程集合
\t\t\tstd::atomic_bool\t\t\tm_bStop = false;// 設置變量為原子性
\t\t\tstd::condition_variable m_vc;\t\t\t\t\t\t// 條件阻塞
\t\t\tstd::queew<ctask> m_quTask;\t\t\t\t// 任務隊列
/<ctask>/<code>
ThreadPool.cpp
<code>#include <mutex>
#include <queue>
#include <atomic>
#include <vector>
#include <thread>
#include <condition>
#include <functional>
#include "ThreadPool.h"
using namespace std:
// 創建線程
CThreadPool::CThreadPool( int iThreadSize)
{
\tm_iIdleCount = iThreadSize;
\tfor( int i=0; i<ithreadsize> {
\t\tCreatThread();
}
}
// 關閉線程池
CThreadPool::~CThreadPool()
{
m_bStop.stor(true);\t // 原子變量操作
m_cv.notify_all();\t\t\t// 條件變量
// 關閉線程。
for( auto& it : m_threads)
{
if(it.joinable)
{
\t\tit.join();
}
}
}
void CThreadPool :: CreateThread()
{
\t\t\tm_thread.emplace_back(&CThreadPool::ThreadWork, this);\t// C++11 新用法
}
// 線程池運轉
void CThreadPool::ThreadWork(PVOID lpParam)
{
\tCThreadPool* pPool = (CThreadPool*)lpParam;
\tif(pPool == NULL) return;
\tCTask* pTask = NULL:\t\t// 要取出來並執行的任務
while((pPool->m_bStop).load() != true)
{
\t\t// 上鎖取任務
\tstd::unique_lock<:mutex> unLock(pPool->m_mtLock);
\tpPool->m_cv.wait(unLock,
[pPool]{
return (pPool->m_bStop).load() || !pPool->m_quTask.empty();}
\t\t\t\t\t\t\t);
\t\t\t
\t\t\tif(pPool->m_bStop).load() && pPool->m_quTask.empty())
return;
\t\t\tpTask = pPool->m_quTask.front();
\t\t\tpPool->m_quTask.pop();
}
\t\tpPool->m_iIdleCount--;
\t\tpPool->HandleTask(pTask);
\t\tpPool->m_iIdleCount++;
}
void CThreadPool::SetThreadCount(int iCount)
{
\tif( iCount > m_threads.size())
{
\t\tfor(int i =0; i< m_thread.size() - iCount;i++)
{
\t\tCreateThread();
}
}
}
void CThreadPool::HandleTask(CTask* p)
{
\tif(p == NULL) return;
// 執行分發操作。
std::cout << "handle Task:"<<:this_thread::get_id> // .....
}
// 線程池的數據入口
void CThreadPool::AddTask(CTask* p)
{
\tif(p == NULL)
return ;
std::lock_guard<:mutex> mtLock(this->m_mtLock);
m_quTask.push(p);
this->m_cv.notify_one(); // 喚醒一個線程
}/<ithreadsize>/<functional>/<condition>/<thread>/<vector>/<atomic>/<queue>/<mutex>/<code>
本文沒有粘貼複製,都是手碼的,避免不了有些錯誤,如果有幫助你的或者有需要的,還請點贊轉發收藏,或者私信我。
閱讀更多 小白說編程 的文章