C++11线程池的创建

#pragma once

#include <vector>
#include <queue>
#include <string>
#include <thread>
#include <future>
#include <memory>
#include <stdexcept>
#include <functional>
#include <condition_variable>
#include "plm_downloader.hpp"
#include <windows.h>

template<class TaskType>
class SafeQueue
{
public:
    SafeQueue(){}
    ~SafeQueue() {}

    bool IsEmpty()
    {
        std::unique_lock<std::mutex> lock(mSQMutex);

        return mSQueue.empty();
    }

    int Size()
    {
        std::unique_lock<std::mutex> lock(mSQMutex);

        return mSQueue.size();
    }

    void Push(TaskType& iData)
    {
        std::unique_lock<std::mutex> lock(mSQMutex);

        mSQueue.emplace(iData);
    }

    bool Pop(TaskType& oData)
    {
        std::unique_lock<std::mutex> lock(mSQMutex);

        if (mSQueue.empty())
        {
            return false;
        }

        oData = std::move(mSQueue.front());
        mSQueue.pop();
        return true;
    }
private:
    std::queue<TaskType> mSQueue;
    std::mutex mSQMutex;
};


class ThreadPool 
{
public:
    ThreadPool()
        :mIsClosePool(false)
    {}
    ThreadPool(const ThreadPool&) = delete;
    ThreadPool(ThreadPool&&) = delete;
    ThreadPool& operator=(const ThreadPool&) = delete;
    ThreadPool& operator=(ThreadPool&&) = delete;

    ~ThreadPool()
    {}

    void Init()
    {
        mVectThreadsPool.clear();
        SYSTEM_INFO Info;
        GetSystemInfo(&Info);
        mThreadNumbersPool = Info.dwNumberOfProcessors + 1;
        mVectThreadsPool.resize(mThreadNumbersPool);
        std::unique_lock<std::mutex> lock(mMutexPool);

        for (int i = 0; i < mThreadNumbersPool; i++)
        {
            mVectThreadsPool.at(i) = std::thread(Thread(this, i));
        }
    }

    template<class F, class... Args>
    auto PushTask(F&& f, Args&& ...args) -> std::future<decltype(f(args...))>
    {
        using RetType = decltype(f(args...));
        auto task = std::make_shared<std::packaged_task<RetType()>>(std::bind(std::forward<F>(f), std::forward<Args>(args)...));


        std::function<void()> TaskFunc = [task]()
        {
            (*task)();
        };
        mSQueuePool.Push(TaskFunc);
        mConditionPool.notify_all();

        return task->get_future();
    }

    void Close()
    {
        mIsClosePool = true;
        mConditionPool.notify_all();

        for (int i = 0; i < mThreadNumbersPool; i++)
        {
            if (mVectThreadsPool.at(i).joinable())
            {
                mVectThreadsPool.at(i).join();
                std::thread::id id = mVectThreadsPool.at(i).get_id();
            }
        }
    }

private:
    SafeQueue<std::function<void()>> mSQueuePool;
    std::vector<std::thread> mVectThreadsPool;
    int mThreadNumbersPool;
    bool mIsClosePool;

private:
    std::mutex mMutexPool;
    std::condition_variable mConditionPool;

private:
    class Thread
    {
    public:
        Thread(ThreadPool* pool, int id)
            :mCTPool(pool),
            mId(id)
        {}

        ~Thread()
        {}

        void operator()()
        {
            std::function<void()> func;

            bool IsPop;
            while (!mCTPool->mIsClosePool)
            {
                std::unique_lock<std::mutex> lock(mCTPool->mMutexPool);
                if (mCTPool->mSQueuePool.IsEmpty())
                {
                    mCTPool->mConditionPool.wait_for(lock, std::chrono::seconds(1));
                }

                IsPop = mCTPool->mSQueuePool.Pop(func);

                if (IsPop)
                {
                    func();
                }
            }

        }
    private:
        int mId;
        ThreadPool* mCTPool;
    };
};

C++11线程池涉及到锁,条件变量,安全队列(STL不是线程安全),线程库新特性,bind等机制。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值