走进C++11(二十九) 将工作打包成任务,丢给执行者 -- std::packaged_task

图片

 

其实std::packaged_task并没有引入新的概念, 它是一个包装类,它包装任何可调用 (Callable) 目标(函数、 lambda 表达式、 bind 表达式或其他函数对象),使得能异步调用它。其返回值或所抛异常被存储于能通过 std::future 对象访问的共享状态中。 

 

如 std::function , std::packaged_task 是多态、具分配器的容器:可在堆上或以提供的分配器分配存储的可调用对象。 

 

std::packaged_task本身很简单,但是却给了我们很多想象空间,这篇文章就不展开讲它的具体应用场景。我会在下一篇文章描述一下怎么利用packaged_task, 100行实现thread pool,敬请期待。

 

下面我们来看一下具体的定义:

 

std::packaged_task

 

 

定义于头文件 <future>

  

template< class > class packaged_task; // 不定义

(1)(C++11 起)

template< class R, class ...Args >
class packaged_task<R(Args...)>;

(2)(C++11 起)

 

下边是一些比较枯燥的API解释, 不喜欢看可以略过,直接看例子。

 

成员函数

 

(构造函数)

构造任务对象
(公开成员函数)

(析构函数)

析构任务对象
(公开成员函数)

operator=

移动任务对象
(公开成员函数)

valid

检查任务对象是否拥有合法函数
(公开成员函数)

swap

交换二个任务对象
(公开成员函数)

获取结果

get_future

返回与承诺的结果关联的 std::future
(公开成员函数)

执行

operator()

执行函数
(公开成员函数)

make_ready_at_thread_exit

执行函数,并确保结果仅在一旦当前线程退出时就绪
(公开成员函数)

reset

重置状态,抛弃任何先前执行的存储结果
(公开成员函数)

 

非成员函数

 

std::swap(std::packaged_task)

(C++11)

特化 std::swap 算法
(函数模板)

 

辅助类

 

std::uses_allocator<std::packaged_task>

(C++11)(C++17 前)

特化 std::uses_allocator 类型特征  
(类模板特化)

 

例子:

 

#include <iostream>#include <future>#include <thread>int main(){// 将一个返回值为7的 lambda 表达式封装到 task 中// std::packaged_task 的模板参数为要封装函数的类型std::packaged_task<int()> task([](){return 7;});// 获得 task 的 futurestd::future<int> result = task.get_future(); // 在一个线程中执行 taskstd::thread(std::move(task)).detach(); std::cout << "Waiting...";result.wait();// 输出执行结果std::cout << "Done!" << std:: endl << "Result is " << result.get() << '\n';}

 

例子2:

#include <iostream>#include <cmath>#include <thread>#include <future>#include <functional> // 避免对 std::pow 重载集消歧义的独有函数int f(int x, int y) { return std::pow(x,y); } void task_lambda(){    std::packaged_task<int(int,int)> task([](int a, int b) {        return std::pow(a, b);     });    std::future<int> result = task.get_future();     task(2, 9);     std::cout << "task_lambda:\t" << result.get() << '\n';} void task_bind(){    std::packaged_task<int()> task(std::bind(f, 2, 11));    std::future<int> result = task.get_future();     task();     std::cout << "task_bind:\t" << result.get() << '\n';} void task_thread(){    std::packaged_task<int(int,int)> task(f);    std::future<int> result = task.get_future();     std::thread task_td(std::move(task), 2, 10);    task_td.join();     std::cout << "task_thread:\t" << result.get() << '\n';} int main(){    task_lambda();    task_bind();    task_thread();}

 

输出:

 

task_lambda: 512task_bind:   2048task_thread: 1024

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值