C++ 并发编程指南(13)线程池原理与实践 | 13.2、关键组件实现


前言:

一、关键组件实现

1、任务队列

任务队列的主要功能是保存要执行的任务,有下面这些需要解决的问题

问题一:如何保证任务的通用性?

因为任务队列要有通用性,所以规定任务队列中存储的类型为

using Task = std::packaged_task<void()>;

因为要投递任务给线程池,任务的功能和参数都不同,而之前设置的线程池执行的task类型为void(void),返回值为void,参数为void的任务。那可用参数绑定的方式将一个函数绑定为void(void)类型,例如:

int functionint(int param) {
    std::cout << "param is " << param << std::endl;
    return 0;
}

void bindfunction() {
    std::function<int(void)> functionv = std::bind(functionint, 3);
    functionv();
}

假设希望任务队列里的任务要调用functionint函数参数为3,因为在投递任务时就知道任务要执行的函数和参数,所以可以将执行的函数和参数绑定生成参数为void的函数。通过bindfunctionfunctionint绑定为一个返回值为int参数为void的新函数functionv,如下:

void pushtasktoque() {
    std::function<int(void)> functionv = std::bind(functionint, 3);
    using Task = std::packaged_task<void()>;
    std::queue<Task> taskque;
    taskque.emplace([functionv]() {
        functionv();
    });
}

上面只是通过具体的函数和参数实现了投递任务的功能,而实际情况是要投递各种类型的任务,以及多种类型和多个参数,该怎么实现enqueue函数更通用呢?对于更通用的设计通常采用模板,如下:

在这里插入代码片

实际投递任务的接口实现如下:

template<class F, class... Args>
auto ThreadPool::enqueue(F&& f, Args&&... args)
    -> std::future<typename std::result_of<F(Args...)>::type>
{
    using return_type = typename std::result_of<F(Args...)>::type;

    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(queue_mutex);

        // don't allow enqueueing after stopping the pool
        if (stop)
            throw std::runtime_error("enqueue on stopped ThreadPool");

        tasks.emplace([task](){ (*task)(); });
    }
    condition.notify_one();
    return res;
}

问题二:如何获取任务是否完成?

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值