C++11實現線程池

//
// Created by krislyy on 2018/11/14.
//

#ifndef ALGORITHM_THREADPOOL_H
#define ALGORITHM_THREADPOOL_H

#include <vector>
#include <queue>
#include <memory>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <future>
#include <functional>
#include <stdexcept>

class ThreadPool {
public:
    ThreadPool(size_t);
    ~ThreadPool();

    template<class F, class... Args>
    std::future<typename std::result_of<F(Args...)>::type> enqueue(F&& f, Args&&... args);

private:
    // need to keep track of threads so we can join them
    std::vector< std::thread > workers;
    // the task queue
    std::queue< std::function<void()> > tasks;

    // synchronization
    std::mutex queue_mutex;
    std::condition_variable condition;
    bool stop;
};

// the constructor just launches some amount of workers
inline ThreadPool::ThreadPool(size_t threads)
        :   stop(false) {
    for (size_t i = 0; i < threads; ++i) {
        workers.emplace_back(
            [this] () ->void {
                for (;;) {
                    std::function<void()> task;
                    {
                        std::unique_lock<std::mutex> lock(this->queue_mutex);
                        this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); });
                        if (this->stop && this->tasks.empty())
                            return;
                        task = std::move(this->tasks.front());
                        this->tasks.pop();
                    }
                    task();
                }
            }
        );
    }
}

// add new work item to the pool
template<class F, class... Args>
std::future<typename std::result_of<F(Args...)>::type> ThreadPool::enqueue(F&& f, Args&&... args)
{
    using return_type = typename std::result_of<F(Args...)>::type;

    auto task = std::make_shared< std::packaged_task<return_type()> >(
            std::bind(std::forward<F>(f), std::forward<Args>(args)...)
    );

    std::future<return_type> res = task->get_future();
    {
        std::unique_lock<std::mutex> lock(queue_mutex);

        // don't allow enqueueing after stopping the pool
        if(stop){
            throw std::runtime_error("enqueue on stopped ThreadPool");
        }

        tasks.emplace([task](){ (*task)(); });
    }
    condition.notify_one();
    return res;
}

// the destructor joins all threads
inline ThreadPool::~ThreadPool()
{
    {
        std::unique_lock<std::mutex> lock(queue_mutex);
        stop = true;
    }
    condition.notify_all();
    for(std::thread &worker: workers)
        worker.join();
}

#endif //ALGORITHM_THREADPOOL_H

//測試代碼

cout << "http:///////////////////////////////////" << endl;
    ThreadPool pool(4);
    std::vector< std::future<int> > results;

    for(int i = 0; i < 8; ++i) {
        results.emplace_back(
                pool.enqueue([i](){
                    cout << "thread id: " << std::this_thread::get_id() << endl;
                    std::this_thread::sleep_for(std::chrono::milliseconds(500));
                    return i*i;
                })
        );
    }

    for(auto && result: results)
        std::cout << result.get() << ' ';

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末惶桐,一起剝皮案震驚了整個濱河市叹侄,隨后出現的幾起案子飒泻,更是在濱河造成了極大的恐慌,老刑警劉巖穗泵,帶你破解...
    沈念sama閱讀 210,835評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異赔嚎,居然都是意外死亡魄咕,警方通過查閱死者的電腦和手機鞋拟,發(fā)現死者居然都...
    沈念sama閱讀 89,900評論 2 383
  • 文/潘曉璐 我一進店門骂维,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人贺纲,你說我怎么就攤上這事航闺。” “怎么了猴誊?”我有些...
    開封第一講書人閱讀 156,481評論 0 345
  • 文/不壞的土叔 我叫張陵潦刃,是天一觀的道長。 經常有香客問我懈叹,道長乖杠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,303評論 1 282
  • 正文 為了忘掉前任澄成,我火速辦了婚禮胧洒,結果婚禮上畏吓,老公的妹妹穿的比我還像新娘。我一直安慰自己卫漫,他們只是感情好菲饼,可當我...
    茶點故事閱讀 65,375評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著列赎,像睡著了一般宏悦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上包吝,一...
    開封第一講書人閱讀 49,729評論 1 289
  • 那天饼煞,我揣著相機與錄音,去河邊找鬼漏策。 笑死派哲,一個胖子當著我的面吹牛,可吹牛的內容都是我干的掺喻。 我是一名探鬼主播芭届,決...
    沈念sama閱讀 38,877評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼感耙!你這毒婦竟也來了褂乍?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,633評論 0 266
  • 序言:老撾萬榮一對情侶失蹤即硼,失蹤者是張志新(化名)和其女友劉穎逃片,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體只酥,經...
    沈念sama閱讀 44,088評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡褥实,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,443評論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了裂允。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片损离。...
    茶點故事閱讀 38,563評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖绝编,靈堂內的尸體忽然破棺而出僻澎,到底是詐尸還是另有隱情,我是刑警寧澤十饥,帶...
    沈念sama閱讀 34,251評論 4 328
  • 正文 年R本政府宣布窟勃,位于F島的核電站,受9級特大地震影響逗堵,放射性物質發(fā)生泄漏秉氧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,827評論 3 312
  • 文/蒙蒙 一蜒秤、第九天 我趴在偏房一處隱蔽的房頂上張望谬运。 院中可真熱鬧隙赁,春花似錦、人聲如沸梆暖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,712評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽轰驳。三九已至厚掷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間级解,已是汗流浹背冒黑。 一陣腳步聲響...
    開封第一講書人閱讀 31,943評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留勤哗,地道東北人抡爹。 一個月前我還...
    沈念sama閱讀 46,240評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像芒划,于是被迫代替她去往敵國和親冬竟。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,435評論 2 348