线程池

代码主要是做练习用的,水平有限,路过的大神看到代码有哪里不好的请帮忙指出来,万分感谢。

#pragma once

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

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

    ThreadPool()
    {}

    ~ThreadPool()
    {
        mbRunning.store(false);
        moCondVar.notify_all();
        for (auto th = mvecThreads.begin(); th != mvecThreads.end(); th++)
        {
            if ((*th).joinable())
            {
                (*th).join();
            }
        }
    }

    void mvInit(int iSize)
    {
        mbRunning.store(true);
        miThreadSize = iSize;

        for (int i = 0; i < iSize; i++)
        {
            mvecThreads.emplace_back(
                [this]
            {
                while (mbRunning.load())
                {
                    Task task;
                    {
                        std::unique_lock<std::mutex> lock(moMutex);
                        moCondVar.wait(lock, [this] {return !mbRunning.load() || !mqueTasks.empty(); });
                        if (!mbRunning.load())
                        {
                            break;
                        }

                        task = mqueTasks.front();
                        mqueTasks.pop();
                    }

                    task();
                }
            });
        }
    }

    template<typename F, typename... Args>
    decltype(auto) mAddTask(F&& f, Args&&... args)
    {
        if (!mbRunning.load())
        {
            //error
            throw std::runtime_error("ThreadPool::mAddTask add task on threadpool stoped!");
        }
        //using return_type = typename std::result_of_t<F(Args...)>;
        using return_type = decltype(f(args...));
        // 这里不知道为啥要用指针,我开始是写的下面注释掉那段代码,老报错,
        // 还没搞清楚问题在哪,求路过的大神指教
        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(moMutex);
            mqueTasks.emplace([task] {(*task)(); });
        }
        
        //using return_type = decltype(f(args...));
        //auto task = 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(moMutex);
        //    mqueTasks.emplace([task] {(task)(); });
        //}

        moCondVar.notify_one();
        return res;
    }

private:
    ThreadPool(const ThreadPool&) = delete;

    ThreadPool(ThreadPool&&) = delete;

    ThreadPool& operator=(const ThreadPool&) = delete;

    ThreadPool& operator=(ThreadPool&&) = delete;

private:
    int miThreadSize = 0;
    std::vector<std::thread> mvecThreads;
    std::queue<Task > mqueTasks;

    std::mutex moMutex;
    std::condition_variable moCondVar;

    std::atomic<bool> mbRunning{ false };
};

int fun1(int a, int b)
{
    std::cout << "run fun1" << std::endl;
    return a + b;
}

std::string fun2()
{
    std::cout << "run fun2" << std::endl;
    return std::move("hello");
}
void test()
{
    ThreadPool pool;
    pool.mvInit(5);
    auto res1 = pool.mAddTask(fun1, 2, 3);
    auto res2 = pool.mAddTask(fun2);
    auto res3 = pool.mAddTask([] {std::cout << "run fun3" << std::endl; });

    int r1 = res1.get();
    std::string s1 = res2.get();

    std::cout << "fun1=" << r1 << std::endl;
    std::cout << "fun2=" << s1 << std::endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值