熱線電話:0755-23712116
郵箱:contact@shuangyi-tech.com
地址:深圳市寶安區(qū)沙井街道后亭茅洲山工業(yè)園工業(yè)大廈全至科技創(chuàng)新園科創(chuàng)大廈2層2A
那么為什么我們需要線程池技術(shù)呢?多線程編程用的好好的,干嘛還要引入線程池這個東西呢?引入一個新的技術(shù)肯定不是為了裝酷,肯定是為了解決某個問題的,而服務(wù)端一般都是效率問題。
我們可以看到多線程提高了CPU的使用率和程序的工作效率,但是如果有大量的線程,就會影響性能,因為要大量的創(chuàng)建與銷毀,因為CPU需要在它們之間切換。線程池可以想象成一個池子,它的作用就是讓每一個線程結(jié)束后,并不會銷毀,而是放回到線程池中成為空閑狀態(tài),等待下一個對象來使用。
但是讓人遺憾的是,C++并沒有在語言級別上支持線程池技術(shù),總感覺C++委員會對多線程的支持像是猶抱琵琶半遮面的羞羞女一樣,無法完全的放開。
雖然無法從語言級別上支持,但是我們可以利用條件變量和互斥鎖自己實現(xiàn)一個線程池。這里就不得不啰嗦幾句,條件變量和互斥鎖就像兩把利劍,幾乎可以實現(xiàn)多線程技術(shù)中的大部分問題,不管是生產(chǎn)消費者模型,還是線程池,亦或是信號量,所以我們必須好好掌握好這兩個工具。
#ifndef _THREADPOOL_H
#define _THREADPOOL_H
#include <vector>
#include <queue>
#include <thread>
#include <iostream>
#include <condition_variable>
using namespace std;
const int MAX_THREADS = 1000; //最大線程數(shù)目
template <typename T>
class threadPool
{
public:
threadPool(int number = 1);
~threadPool();
bool append(T *task);
//工作線程需要運行的函數(shù),不斷的從任務(wù)隊列中取出并執(zhí)行
static void *worker(void *arg);
void run();
private:
//工作線程
vector<thread> workThread;
//任務(wù)隊列
queue<T *> taskQueue;
mutex mt;
condition_variable condition;
bool stop;
};
template <typename T>
threadPool<T>::threadPool(int number) : stop(false)
{
if (number <= 0 || number > MAX_THREADS)
throw exception();
for (int i = 0; i < number; i++)
{
cout << "create thread:" << i << endl;
workThread.emplace_back(worker, this);
}
}
template <typename T>
inline threadPool<T>::~threadPool()
{
{
unique_lock<mutex> unique(mt);
stop = true;
}
condition.notify_all();
for (auto &wt : workThread)
wt.join();
}
template <typename T>
bool threadPool<T>::append(T *task)
{
//往任務(wù)隊列添加任務(wù)的時候,要加鎖,因為這是線程池,肯定有很多線程
unique_lock<mutex> unique(mt);
taskQueue.push(task);
unique.unlock();
//任務(wù)添加完之后,通知阻塞線程過來消費任務(wù),有點像生產(chǎn)消費者模型
condition.notify_one();
return true;
}
template <typename T>
void *threadPool<T>::worker(void *arg)
{
threadPool *pool = (threadPool *)arg;
pool->run();
return pool;
}
template <typename T>
void threadPool<T>::run()
{
while (!stop)
{
unique_lock<mutex> unique(this->mt);
//如果任務(wù)隊列為空,就停下來等待喚醒,等待另一個線程發(fā)來的喚醒請求
while (this->taskQueue.empty())
this->condition.wait(unique);
T *task = this->taskQueue.front();
this->taskQueue.pop();
if (task)
task->process();
}
}
#endif
#include "threadPool.h"
#include <string>
using namespace std;
class Task
{
private:
int total = 0;
public:
void process();
};
//任務(wù)具體實現(xiàn)什么功能,由這個函數(shù)實現(xiàn)
void Task::process()
{
//這里就輸出一個字符串
cout << "task successful! " << endl;
this_thread::sleep_for(chrono::seconds(1));
}
template class std::queue<Task>;
int main(void)
{
threadPool<Task> pool(1);
std::string str;
while (1)
{
Task *task = new Task();
pool.append(task);
delete task;
}
}
以上就是線程池的實現(xiàn)部分,充分利用條件變量和互斥鎖來實現(xiàn),模型可以參考生產(chǎn)消費者模型。以上代碼部分來自網(wǎng)絡(luò),根據(jù)自己的需求更改。