熱(re)線電話(hua):0755-23712116
郵箱:contact@legoupos.cn
地(di)址:深圳(zhen)市寶(bao)安區沙井街道后亭茅洲(zhou)山工(gong)業園工(gong)業大廈全(quan)至科(ke)技創(chuang)新(xin)園科(ke)創(chuang)大廈2層2A
那么為什么我們需要線(xian)程(cheng)池技術呢?多線(xian)程(cheng)編程(cheng)用的(de)(de)好好的(de)(de),干嘛(ma)還要引入(ru)線(xian)程(cheng)池這個(ge)東西呢?引入(ru)一個(ge)新(xin)的(de)(de)技術肯(ken)定(ding)不是(shi)為了裝酷,肯(ken)定(ding)是(shi)為了解決某個(ge)問(wen)題的(de)(de),而服務端一般都是(shi)效率問(wen)題。
我們(men)可以看到多線(xian)程提(ti)高了CPU的使(shi)用(yong)率(lv)和(he)程序的工作效率(lv),但是(shi)如果(guo)有大量的線(xian)程,就會影響性能,因為要(yao)大量的創建(jian)與銷(xiao)(xiao)毀,因為CPU需要(yao)在它們(men)之間(jian)切換(huan)。線(xian)程池(chi)可以想象(xiang)成一個池(chi)子,它的作用(yong)就是(shi)讓每(mei)一個線(xian)程結束后(hou),并不會銷(xiao)(xiao)毀,而是(shi)放回到線(xian)程池(chi)中成為空閑狀態,等待下一個對象(xiang)來使(shi)用(yong)。
但是(shi)(shi)讓人遺憾(han)的是(shi)(shi),C++并沒有在語言(yan)級(ji)別上(shang)支持線程池技術,總感覺C++委員會對多線程的支持像(xiang)是(shi)(shi)猶抱琵琶半遮面的羞羞女一(yi)樣,無法(fa)完全的放開。
雖然無法從語言級別上支持,但是我們可以利用條件變量和互斥鎖自己實現一個線程池。這(zhe)里就不(bu)得不(bu)啰嗦幾(ji)句,條件變量和互斥(chi)鎖就像兩(liang)把(ba)利劍,幾(ji)乎(hu)可以(yi)實現多線程(cheng)技術中的大部分(fen)問題,不(bu)管是(shi)生產消費者模(mo)型(xing),還(huan)是(shi)線程(cheng)池,亦或(huo)是(shi)信號量,所以(yi)我(wo)們必須好(hao)好(hao)掌握好(hao)這(zhe)兩(liang)個工具(ju)。
#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; //最大線程數目
template <typename T>
class threadPool
{
public:
threadPool(int number = 1);
~threadPool();
bool append(T *task);
//工作線程需要運(yun)行的函數,不斷的從任務隊(dui)列中取出并執(zhi)行
static void *worker(void *arg);
void run();
private:
//工作(zuo)線程
vector<thread> workThread;
//任務(wu)隊列
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)
{
//往任(ren)務隊列(lie)添加任(ren)務的時候,要加鎖(suo),因為這是線(xian)(xian)程(cheng)(cheng)池(chi),肯定有很多線(xian)(xian)程(cheng)(cheng)
unique_lock<mutex> unique(mt);
taskQueue.push(task);
unique.unlock();
//任務添加完之后,通知阻塞線程(cheng)過來消費(fei)任務,有點像生產消費(fei)者模型
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);
//如果任務隊(dui)列(lie)為空,就停下來等待喚醒,等待另一個線程發來的喚醒請求
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();
};
//任(ren)務具體實現什么功(gong)能,由(you)這個(ge)函數(shu)實現
void Task::process()
{
//這里就輸出一個字(zi)符串
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;
}
}
以上(shang)就是線程(cheng)池(chi)的實現(xian)部分(fen),充分(fen)利用(yong)條件變量和互斥鎖來實現(xian),模型(xing)(xing)可(ke)以參考生產消費者模型(xing)(xing)。以上(shang)代(dai)碼(ma)部分(fen)來自網絡,根據自己的需求更(geng)改。