要點
- 執行緒池,功能是管理執行緒資源,管理任務佇列。空閒執行緒從任務佇列中取出任務完成,需要執行緒時將任務掛在任務對列。
- 由於對任務佇列的操作要實現同步,引入了互斥訊號量和條件變數。
- 當執行緒池生命週期結束時,不允許再掛載任務,引入一個原子變數stop_flag
- 實現執行緒池ThreadPool類,成員變數有:
- vector : workers
- queue<function<void()>> : tasks
- mtx : mutex
- cv :conditon_vatiable
- stop_flag : atomic
- 實現執行緒池ThreadPool類,成員函式有:
- ThreadPool(int size) : 開闢大小為size的執行緒池,建立size個執行緒worker存在workers裡,安排worker從tasks中取出任務執行
- void puts(Function<void()>&& F) : 把任務f掛在任務佇列tasks下
- ~ThreadPool() : stop並join結束所有執行緒
程式碼實現
#include <iostream>
#include <vector>
#include <queue>
#include <thread>
#include <memory>
#include <mutex>
#include <atomic>
#include <functional>
using namespace std;
class ThreadPool {
private:
vector<thread> workers;
queue<function<void()>> tasks;
mutex mtx_for_que;
condition_variable cv;
atomic<bool> stop_flag;
public:
ThreadPool(int size);
void make_Task(function<void()>&& f);
~ThreadPool();
};
ThreadPool::ThreadPool(int size) : stop_flag(false) {
for (int i = 0; i < size; ++i) {
workers.emplace_back([this]() {
for (;;) {
unique_lock<mutex> ulock(this->mtx_for_que);
while (!this->stop_flag && this->tasks.empty()) {
this->cv.wait(ulock);
}
if (this->stop_flag && this->tasks.empty()) {
return;
}
function<void()> task = move(this->tasks.front());
this->tasks.pop();
// 執行
task();
}
});
}
}
void ThreadPool::make_Task(function<void()>&& f) {
function<void()> task = f;
unique_lock<mutex> ulock(mtx_for_que);
if (stop_flag) {
cout << "This ThreadPool has been stopped!" << endl;
return;
}
tasks.emplace([task]() {(task)(); });
cv.notify_one();
return;
}
ThreadPool::~ThreadPool() {
stop_flag = true;
cv.notify_all();
for (auto& worker : workers) {
worker.join();
}
return;
}
int main() {
ThreadPool pool(4);
for (int i = 0; i < 20; ++i) {
pool.make_Task([i]() {
cout << i << endl;
});
}
return 0;
}