结合C++11新特性实现一个通用高效线程库

基本上常用的新特性都用上了,可以作为学习C++11新特性的一个很好的例子。

源码如下

#pragma once
#include <mutex>
#include <condition_variable>
#include <queue>
#include <thread>
#include <functional>
#include <assert.h>

class ThreadPool {
public:
	explicit ThreadPool(size_t threadCount = 8) :pool_(std::make_shared<Pool>()) {//make_shared创建Pool对象,并返回指针类似new
		assert(threadCount > 0);
		for (size_t i = 0; i < threadCount; ++i) {
            std::thread th([this]() {
                std::unique_lock<std::mutex> locker(pool_->mtx);
                while (true) {
                    if (!pool_->tasks.empty()) {
                        auto task = std::move(pool_->tasks.front());
                        pool_->tasks.pop();
                        locker.unlock();
                        task();
                        locker.lock();
                    }
                    else if (pool_->isClosed) break;
                    else pool_->cond.wait(locker);
                }
             });
            th.detach();
		}
	}
    ThreadPool() = default;
    ThreadPool(ThreadPool&&) = default;
    ~ThreadPool() {
        //通知销毁线程了
        if (static_cast<bool>(pool_)) {
            {
                std::lock_guard<std::mutex> locker(pool_->mtx);
                pool_->isClosed = true;
            }
            pool_->cond.notify_all();
        }
    }
    template<class T>
    void AddTask(T&& task) {
        {
            std::lock_guard<std::mutex> locker(pool_->mtx);
            pool_->tasks.emplace(std::forward<T>(task));
        }
        pool_->cond.notify_one();
    }
private:
    struct Pool {
        std::mutex mtx;
        std::condition_variable cond;
        bool isClosed;
        std::queue <std::function<void()>> tasks;
    };
	std::shared_ptr<Pool> pool_;
};

使用

#include <iostream>
#include <string>
#include "threadpool.h"
using namespace std;

void myfunc1(int x) {
    static int i = 0;
    cout << "test" << i << endl;
    i++;
}

void test() {
    ThreadPool pool(8);
    string str = "hello world";
    for (int i = 0; i < 1000; ++i) {
        pool.AddTask(bind(myfunc1, i));
        pool.AddTask(bind([&](string x) {
            cout << str << x << endl;
            }, to_string(i)));
    }
}
posted @ 2022-03-13 16:10  misaka-mikoto  阅读(94)  评论(0编辑  收藏  举报