0
点赞
收藏
分享

微信扫一扫

Windows 10 系统安装 FFmpeg 查看、转换、编辑音频文件

回溯 2024-09-30 阅读 12
c++rabbitmq

文章目录

一.C++11 中的

二.future 对象

三.async 全局函数

#include <iostream>
#include <future>
#include <chrono>
#include <thread>

int Add(int x, int y)
{
    std::this_thread::sleep_for(std::chrono::seconds(5));
    return x + y;
}
int main()
{
    std::future<int> fu =  std::async(std::launch::async, Add, 1, 2);
    int ret = fu.get();

    std::cout << "ret = " << ret << std::endl;
    return 0;
}

四.promise::get_future

#include <iostream>
#include <future>
#include <chrono>
#include <thread>

int Add(int x, int y)
{
    std::this_thread::sleep_for(std::chrono::seconds(5));
    return x + y;
}
int main()
{
    std::future<int> fu =  std::async(std::launch::async, Add, 1, 2);

    int ret = fu.get();

    std::cout << "ret = " << ret << std::endl;
    return 0;
}

五.packaged_task::get_future

#include <iostream>
#include <future>
#include <chrono>
#include <thread>
#include <memory>
using namespace std;
int Add(int x, int y)
{
    std::this_thread::sleep_for(std::chrono::seconds(5));
    return x + y;
}
int main()
{

    auto ptaskPtr = std::make_shared<packaged_task<int(int, int)>>(Add);
    future<int> fu = ptaskPtr->get_future();
    thread t1([ptaskPtr]{
        (*ptaskPtr)(1, 2);
    });
    int ret = fu.get();
    std::cout << ret << std::endl;
    t1.join();
    
    return 0;
}

六.使用 packaged_task 和 future 实现可获取结果的线程池

ThreadPool.hpp

#pragma once
#include <thread>
#include <mutex>
#include <condition_variable>
#include <memory>
#include <atomic>
#include <vector>
#include <queue>
#include <functional>
#include <iostream>
#include <future>
static const int defaultThreadNum = 5;
class ThreadPool
{
public:
    using task_t = std::function<void()>;

private:
    std::vector<std::thread> _workers;
    std::queue<task_t> _tasks;
    std::mutex _mtx;
    std::condition_variable _cond;
    std::atomic<bool> _isRunning;
    int _threadNum;

public:
    ThreadPool(int threadNum = defaultThreadNum)
        : _workers(),
          _tasks(),
          _mtx(),
          _cond(),
          _isRunning(false),
          _threadNum(threadNum)
    {
    }

    ~ThreadPool()
    {
        for (auto& t : _workers)
        {
            t.join();
        }
    }

    void start()
    {
        for (int i = 0; i < _threadNum; i++)
        {
            _workers.emplace_back(&ThreadPool::work, this);
        }
        _isRunning = true;
    }

    template <typename Fn, typename ...Args>
    auto push(Fn&& func, Args&& ... args) -> std::future<decltype(func(args...))>
    {
        using return_t = decltype(func(args...));
        if (!_isRunning)
        {
            std::cout << "Please start threadPool first" << std::endl;
            return std::future<return_t>();
        }
       
        //1.把这个任务的参数绑定,变成一个返回值位return_t,参数为void的可调用对象
        auto tmpFunc = std::bind(std::forward<Fn>(func), std::forward<Args>(args)...);

        //2.把这个bind后的可调用对象用packaged_task封装,用智能指针管理
        auto ptaskPtr = std::make_shared<std::packaged_task<return_t()>>(tmpFunc);
        
        //3.把智能指针封装到lambda表达式中解引用执行,并把lambda表达式丢进任务队列
        task_t task = [ptaskPtr](){(*ptaskPtr)();};

        std::unique_lock<std::mutex> lck(_mtx);
        _tasks.push(task);
        _cond.notify_one();
        return ptaskPtr->get_future();
    }

private:
    void work()
    {
        while (true)
        {
            task_t task;
            {
                std::unique_lock<std::mutex> lck(_mtx);
                // 判断条件是否成立
                while (_tasks.empty())
                {
                    _cond.wait(lck);
                }
                task = _tasks.front();
                _tasks.pop();
            }
            task();
        }
    }
};
举报

相关推荐

0 条评论