首页 > 编程语言 >C++多线程:package_task

C++多线程:package_task

时间:2024-11-01 19:57:49浏览次数:2  
标签:std task 对象 packaged C++ future 共享 多线程

std::packaged_task

std::packaged_task包装一个可调用对象,并允许获取该可调用对象计算的结果,可调用对象内部包含两个基本元素:
1.被包装的任务
任务是一个可调用对象,如函数指针或函数对象,该对象的执行结果会传递给共享状态
2.共享状态
用于保存任务的返回结果,并可通过future对象异步访问共享状态

packaged_task对象的共享状态的生命周期一直会持续到最后一个与之关联的对象被销毁
示例如下:

#include<iostream>
#include<future>
#include<chrono>
#include<thread>
int countdown(int from, int to){
    for(int i=from; i!=to; --i){
        std::cout<<i<<std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    std::cout<<"finished"<<std::endl;
    return from-to;
}

int main(){
    std::packaged_task<int(int,int)> task(countdown);
    std::future<int> ret= task.get_future();

    std::thread th(std::move(task), 10,0);

    int val= ret.get();
    std::cout<<"the countdown lasted for "<<val<<" seconds"<<std::endl;

    th.join();

    return 0;
}

构造函数

  • default
    packaged_task()noexcept;
    
    初始化一个空的共享状态
  • initialization
    template<class Fn>
    explicit packaged_task(Fn&&);
    
  • with allocator
    template<class Fn, class Alloc>
    explicit packaged_task(allocator_arg_t, const Alloc&, Fn&&);
    

拷贝构造函数

pakcaged_task(const package_task&)=delete;

被禁用,不可拷贝构造

移动构造函数

pakcaged_task(const package_task&&)noexcept;

成员函数

  • std::packaged_task::get_future()
    获取与共享状态关联的future对象

  • std::packaged_task::valid()
    检查packaged_task对象是否与一个有效的共享状态关联
    由默认构造函数生成的packaged_task对象,该函数返回false,除非中间进行了移动赋值或swap操作

    std::future<int> launcher(std::packaged_task<int(int)>& tsk, int arg){
      if(tsk.valid()){
        std::future<int> ret= tsk.get_future();
        std::thread(std::move(tsk),arg).detach();
        return ret;
      }else{
        return std::future<int>();
      }
    }
    
  • std::packaged_task::operator()(Args... args)
    重载operator()运算符,调用packaged_task对象包装的任务(函数指针,函数对象或lambda表达式),传参args

    • 若调用成功,则将返回值传入packaged_task对象的共享状态
    • 若调用失败,则将抛出的异常传入共享状态
      以上两种情况的共享状态标志都会变为ready,因此其他等待该共享状态的线程可以通过std::future::get()获取值或异常对象

    由于被包装的任务在构造packaged_task时指定,因此operator()的效果由该任务决定

    • 若被包装的任务指向函数或函数对象
      std::packaged_task::operator()仅将参数传递给该任务
    • 若被包装的任务指向类的非静态成员函数
      std::packaged_task::operator()的第一个参数应该指定为成员函数被调用的那个对象,其他参数为成员函数的实参
    • 若被包装的任务指向类的非静态成员变量
      std::packaged_task::operator()只允许有一个参数
  • std::packaged_task::make_ready_at_thread_exit()
    会调用被包装的任务,并传递参数,类似于operator(),但make_ready_at_thread_exit()不会立即设置共享状态标志为ready,而是在线程退出时设置
    该函数已经设置了共享状态的值,若在线程结束之前有其他设置或修改共享状态的操作,则会抛出future_error异常

  • std::packaged_task::reset()
    重置packaged_task的共享状态,但是保留之前包装的任务

    #include<iostream>
    #include<utiliy>
    #include<future>
    #include<thread>
    
    int triple(int x){ return x*3; }
    
    int main(){
      std::packaged_task<int(int)> tsk(triple);
      std::future<int> fut= tsk.get_future();
      
      std::thread(std::move(tsk),100).detach();
      std::cout<<"the triple of 100 is:"<<fut.get()<<std::endl;
    
      // re-use same task object
      tsk.reset();
      fut= tsk.get_future();
      std::thread(std::move(tsk),200).detach();
      std::cout<<"the triple of 200 is:"<<fut.get()<<std::endl;
    
      return 0;
    }
    
  • std::packaged_task::swap()
    交换packaged_task对象的共享状态

标签:std,task,对象,packaged,C++,future,共享,多线程
From: https://www.cnblogs.com/sgqmax/p/18521171

相关文章

  • C++标准库:chrono
    ratio先看一下ratio的定义template<intmax_tN,intmax_tD=1>classratio;ratio是由非类型参数定义的模板,用来定义一个比率N/D,如ratio<1,-2>表示-0.5标准库中定义的常用ratio类型typedefinition说明ratio<1,1000>std::milli1/1000ratio<1,1000000>std::mic......
  • C++标准库:random
    随机数生成设备随机数生成设备random_device,生成非确定性随机数,在Linux中通过读取/dev/urandom设备,Windows中使用rand_s重载了()运算符,每次调用会生成一个min()到max()之间的高质量随机数种子,若在Linux(UnixLike)下,可以使用这个生成高质量的随机数,可以理解为真随机数,windows下......
  • Chromium 中chrome.topSites扩展接口定义c++
    一、chrome.topSites使用 chrome.topSites API访问新标签页上显示的热门网站(即最常访问的网站)。不包括用户自定义的快捷方式。权限topSites您必须声明“topSites”扩展程序清单中授予使用此API的权限。{ "name":"Myextension", ... "permissions":[ ......
  • 06程序IPO模式与C++顺序结构
    一、程序IPO模式编程IPO是指输入、处理和输出(Input,Process,Output)的概念。在计算机编程中,IPO是一种常用的设计模式,用于描述程序的基本流程。具体来说,IPO指的是程序从接受输入数据开始,经过一系列处理计算,最终产生输出结果的过程。IPO模式的组成部分:-输入(Input):在这个阶段......
  • 复合结构(C++ Primer)
    复合结构(C++Primer)使用结构体和string使用结构体示例代码:#include<iostream>#include<string>usingnamespacestd;structperson{stringfn;stringsn;chargrade;intage;};intmain(){person*a=newperson;cout<<"what......
  • 【C++】——高效构建与优化二叉搜索树
    活着就意味必须要做点什么,请好好努力。——村上春树《地下》目录1、二叉搜索树BST1.1什么是二叉搜索树1.2BST的性能功能分析2、二叉搜索树的实现2.1BST框架2.2BST插入2.3BST搜索2.4BST删除2.5BST细节问题3、二叉搜索树遍历3.1中序遍历3.2前序遍历3.3......
  • UEC++中的GetClass和StaticClass函数
    GetClass()用途:GetClass() 是 UObject 类的一个实例方法,用于获取调用它的对象的类信息。返回类型:返回 UClass*,即指向调用对象的类的 UClass 对象的指针。使用场景:当你有一个 UObject 或其子类的实例,并且想要获取这个实例所属类的信息时,你会使用 GetClass()。例......
  • UEC++ UClass类
    一、UClass的定义与功能UClass是虚幻引擎中实现反射机制的关键部分,它允许引擎在运行时动态地查询和操作类的信息。每个UClass都保留了一个称作“类默认对象(ClassDefaultObject,简称CDO)”的模板对象,这个对象由类的构造函数生成,并且之后不会被修改。UClass和CDO都可以为特定对......
  • 题解 洛谷 Luogu P1308 [NOIP2011 普及组] 统计单词数 C++
    题目传送门:P1308[NOIP2011普及组]统计单词数-洛谷|计算机科学教育新生态https://www.luogu.com.cn/problem/P1308getline() 会清除使当次getline() 终止的换行,而cin 不会因此cin 以换行终止,之后还需要getline()的话,需要用getchar() 吞换行Linux的一些相......
  • 为什么 C++ 编译速度比 Java 慢得多
    ###为什么C++编译速度比Java慢得多在探讨为什么C++编译速度比Java慢得多时,我们可以归纳出几个核心原因:C++的编译模型更为复杂、模板元编程、宏处理以及链接时间。其中,C++的编译模型更为复杂这一点尤为突出。C++需要处理的细节更多,如模板实例化、头文件的重复包含等,这些......