首页 > 其他分享 >std::packaged_task

std::packaged_task

时间:2024-03-26 12:23:11浏览次数:18  
标签:std task 对象 packaged future 构造函数

std::packaged_task 包装一个可调用的对象,并且允许异步获取该可调用对象产生的结果,从包装可调用对象意义上来讲,std::packaged_taskstd::function 类似,只不过 std::packaged_task 将其包装的可调用对象的执行结果传递给一个 std::future 对象(该对象通常在另外一个线程中获取 std::packaged_task 任务的执行结果)。

std::packaged_task 对象内部包含了两个最基本元素:

  • 被包装的任务(stored task),任务(task)是一个可调用的对象,如函数指针、成员函数指针或者函数对象;
  • 共享状态(shared state),用于保存任务的返回值,可以通过 std::future 对象来达到异步访问共享状态的效果。

可以通过 std::packged_task::get_future 来获取与共享状态相关联的 std::future 对象。在调用该函数之后,两个对象共享相同的共享状态,具体解释如下:

  • std::packaged_task 对象是异步 Provider,它在某一时刻通过调用被包装的任务来设置共享状态的值。
  • std::future 对象是一个异步返回对象,通过它可以获得共享状态的值,当然在必要的时候需要等待共享状态标志变为 ready.

std::packaged_task 的共享状态的生命周期一直持续到最后一个与之相关联的对象被释放或者销毁为止。下面一个小例子大致讲了 std::packaged_task 的用法:

#include <iostream>     // std::cout
#include <future>       // std::packaged_task, std::future
#include <chrono>       // std::chrono::seconds
#include <thread>       // std::thread, std::this_thread::sleep_for

// count down taking a second for each value:
int countdown (int from, int to) {
    for (int i=from; i!=to; --i) {
        std::cout << i << '\n';
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    std::cout << "Finished!\n";
    return from - to;
}

int main ()
{
    std::packaged_task<int(int,int)> task(countdown); // 设置 packaged_task
    std::future<int> ret = task.get_future(); // 获得与 packaged_task 共享状态相关联的 future 对象.

    std::thread th(std::move(task), 10, 0);   //创建一个新线程完成计数任务.

    int value = ret.get();                    // 等待任务完成并获取结果.

    std::cout << "The countdown lasted for " << value << " seconds.\n";

    th.join();
    return 0;
}

std::packaged_task 构造函数

packaged_task() noexcept; 
//default 默认构造函数,初始化一个空的共享状态,并且该 packaged_task 对象无包装任务。

template <class Fn>
  explicit packaged_task (Fn&& fn);
// initialization 初始化一个共享状态,并且被包装任务由参数 fn 指定。

template <class Fn, class Alloc>
  explicit packaged_task (allocator_arg_t aa, const Alloc& alloc, Fn&& fn);
// with allocator 带自定义内存分配器的构造函数,与默认构造函数类似,但是使用自定义分配器来分配共享状态。

packaged_task (const packaged_task&) = delete;
// copy [deleted] 拷贝构造函数,被禁用。

packaged_task (packaged_task&& x) noexcept;
// move 移动构造函数。

下面例子介绍了各类构造函数的用法:

#include <iostream>     // std::cout
#include <utility>      // std::move
#include <future>       // std::packaged_task, std::future
#include <thread>       // std::thread

int main ()
{
    std::packaged_task<int(int)> foo; // 默认构造函数.

    // 使用 lambda 表达式初始化一个 packaged_task 对象.
    std::packaged_task<int(int)> bar([](int x){return x*2;});

    foo = std::move(bar); // move-赋值操作,也是 C++11 中的新特性.

    // 获取与 packaged_task 共享状态相关联的 future 对象.
    std::future<int> ret = foo.get_future();

    std::thread(std::move(foo), 10).detach(); // 产生线程,调用被包装的任务.

    int value = ret.get(); // 等待任务完成并获取结果.
    std::cout << "The double of 10 is " << value << ".\n";

    return 0;
}

 

标签:std,task,对象,packaged,future,构造函数
From: https://www.cnblogs.com/love-9/p/18096386

相关文章

  • C++11标准模板(STL) 算法(std::reverse)
    定义于头文件<algorithm>算法库提供大量用途的函数(例如查找、排序、计数、操作),它们在元素范围上操作。注意范围定义为 [first,last) ,其中 last 指代要查询或修改的最后元素的后一个元素。逆转范围中的元素顺序std::reverse1)反转[first,last)范围中的元素顺序表......
  • C++ std::reverse函数
    函数原型,定义std::reverse定义于头文件 <algorithm>1(1)2template<classBidirIt>3voidreverse(BidirItfirst,BidirItlast);(C++20前)45template<classBidirIt>6constexprvoidreverse(BidirItfirst,BidirItlast);(C++20起)......
  • std::promise
    std::promise的作用就是提供一个不同线程之间的数据同步机制,它可以存储一个某种类型的值,并将其传递给对应的future,即使这个future与promise不在同一个线程中也可以安全的访问到这个值。std::promise<int>promiseObj;可以通过get_future()来获取与该promise对象相关联的......
  • std::atomic 使用
    std::atomic(原子变量)参考文章包括:C++原子变量atomic详解-知乎(zhihu.com)C++中的原子变量(std::atomic)使用指南_std::atomic-CSDN博客cplusplus.com/reference/atomic/atomic/原子变量是C++11中用于多线程编程的便捷工具(同步机制)之一.其提供了一种线程安全的方式来......
  • std::async
    C++11提供了异步接口std::async,通过这个异步接口可以很方便的获取线程函数的执行结果。std::async会自动创建一个线程去调用线程函数,它返回一个std::future,这个future中存储了线程函数返回的结果,当我们需要线程函数的结果时,直接从future中获取,非常方便。但是我想说的是,其实std::as......
  • std::unique_lock
    C++11标准中定义了另外一个与MutexRAII相关类unique_lock,该类与lock_guard类相似,也很方便线程对互斥量上锁,但它提供了更好的上锁和解锁控制。unique_lock对象以独占所有权的方式(uniqueowership)管理mutex对象的上锁和解锁操作,所谓独占所有权,就是没有其他的unique_loc......
  • BPMN2.0基础学习第一篇-Task(任务)
    BPMN2.0-Task(任务)BPMN2.0介绍BPMN(BusinessProessModel&Notation,业务流程模型与符号)2.0规范是OMG(ObjectManagementGroup,对象管理组织)制定的,其主要目的是既给用户提供一套简单的、容易理解的机制,以便用户创建流程模型;又使用户能很好地处理不同流程模型内在的复杂性......
  • std::lock_guard 介绍
    std::lock_gurad是C++11中定义的模板类。定义如下:template <class Mutex>class lock_guard;lock_guard对象通常用于管理某个锁(Lock)对象,因此与MutexRAII相关,方便线程对互斥量上锁,即在某个lock_guard对象的声明周期内,它所管理的锁对象会一直保持上锁状态;而lo......
  • SCHTASKS命令参数 :允许管理员在本地或远程系统上创建、删除、查询、更改、运行和结束
    C:\Windows\System32\Tasks文件夹下的XML文件是用来存储Windows操作系统中计划任务的信息的。Windows操作系统通过这些XML文件来管理和存储各种预定的任务,例如定时备份、系统维护、自动更新等。这些任务可以在特定的时间或事件发生时自动执行,而XML文件则包含了这些任务的配置信......
  • std::vector 和 std::list 区别
    std::vector和std::list区别?std::vector和std::list是C++标准库中两种不同的容器类型,它们之间有以下几个主要区别:存储结构:std::vector是连续内存空间上的动态数组,元素在内存中是连续存储的。std::list是基于双向链表实现的,元素在内存中是非连续存储的。......