c++11实现的线程池

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/GG_SiMiDa/article/details/82388865

HThreadPool

#ifndef H_THREAD_POOL_H
#define H_THREAD_POOL_H

#include <vector>
#include <thread>
#include <queue>
#include <functional>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <future>

class HThreadPool{
public:
    using Task = std::function<void()>;

    HThreadPool(int size = std::thread::hardware_concurrency()) : pool_size(size), idle_num(size), status(STOP){

    }

    ~HThreadPool(){
        stop();
    }

    int start() {
        if (status == STOP) {
            status = RUNNING;
            for (int i = 0; i < pool_size; ++i){
                workers.emplace_back(std::thread([this]{
                    while (status != STOP){
                        while (status == PAUSE){
                            std::this_thread::yield();
                        }

                        Task task;
                        {
                            std::unique_lock<std::mutex> locker(mutex);
                            cond.wait(locker, [this]{
                                return status == STOP || !tasks.empty();
                            });

                            if (status == STOP) return;

                            if (!tasks.empty()){
                                task = std::move(tasks.front());
                                tasks.pop();
                            }
                        }

                        --idle_num;
                        task();
                        ++idle_num;
                    }    
                }));
            }
        }
        return 0;
    }

    int stop() {
        if (status != STOP) {
            status = STOP;
            cond.notify_all();
            for (auto& thread: workers){
                thread.join();
            }
        }
        return 0;
    }

    int pause() {
        if (status == RUNNING) {
            status = PAUSE;
        }
        return 0;
    }

    int resume() {
        if (status == PAUSE) {
            status = RUNNING;
        }
        return 0;
    }

    // return a future, calling future.get() will wait task done and return RetType.
    // commit(fn, args...)
    // commit(std::bind(&Class::mem_fn, &obj))
    // commit(std::mem_fn(&Class::mem_fn, &obj))
    template<class Fn, class... Args>
    auto commit(Fn&& fn, Args&&... args) -> std::future<decltype(fn(args...))>{
        using RetType = decltype(fn(args...));
        auto task = std::make_shared<std::packaged_task<RetType()> >(
            std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...)
        );
        std::future<RetType> future = task->get_future();
        {
            std::lock_guard<std::mutex> locker(mutex);
            tasks.emplace([task]{
                (*task)();
            });
        }

        cond.notify_one();
        return future;
    }

public:
    int pool_size;
    std::atomic<int> idle_num;

    enum Status {
        STOP,
        RUNNING,
        PAUSE,
    };
    std::atomic<Status> status;
    std::vector<std::thread> workers;

    std::queue<Task> tasks;
    std::mutex        mutex;
    std::condition_variable cond;
};

#endif // H_THREAD_POOL_H

TestCase

#include <stdio.h>
#include "hthreadpoo.h"
#include <iostream>

void print_task(int i){
    std::cout << "thread:" << std::this_thread::get_id() << std::endl;
    printf("task[%d]\n", i);
}

int main(int argc, char** argv){
    HThreadPool tp;
    tp.start();

    for (int i = 0; i < 1000; ++i){
        tp.commit(print_task, i);
    }

    std::this_thread::sleep_for(std::chrono::seconds(5));

    tp.stop();

    return 0;
}

猜你喜欢

转载自blog.csdn.net/GG_SiMiDa/article/details/82388865