当前位置: 首页 > 编程日记 > 正文

C++多线程:package_task异步调用任何目标执行操作

文章目录

      • 描述
      • 函数成员及使用
      • 总结

我们上一篇描述关于C++多线程中的异步操作相关库( asyncpromise),本节将分享c++标准库中最后一个多线程异步操作库 package_task的学习笔记。

描述

  • 头文件 <future>

  • 声明方式: template< class R, class ...Args > class packaged_task<R(Args...)>;

  • 简介
    package_task标准类模版包装了任何可调用的目标,其中包括函数,std::bind表达式,lamda表达式或者其他函数对象。并支持package_task对象调用者的异步调用。调用之后的返回值或者产生的异常能够被存储在能够被std::future对象访问的共享状态中。

    综上描述,我们很明显能够体会到该模版类提供的功能和promise类非常接近,但是promise类没有办法初始化所有可调用的对象,promise类仅提供共享状态的多种访问机制并提供线程之间变量的共享机制。

函数成员及使用

  • 构造函数
    packaged_task() noexcept;构造无任务且无共享状态的package_task对象
    template <class F> explicit packaged_task( F&& f ) 构造拥有共享状态和任务副本的 std::packaged_task 对象,
    packaged_task( const packaged_task& ) = delete;复制构造函数被删除, std::packaged_task 仅可移动
    packaged_task( packaged_task&& rhs ) noexcept; rhs 之前所占有的共享状态和任务构造 std::packaged_task ,令 rhs 留在无共享状态且拥有被移动后的任务的状态
    查看如下代码:

    #include <future>
    #include <iostream>
    #include <thread>int fib(int n)
    {if (n < 3) return 1;else {std::cout << "fib  result " << (n-1)+(n-2) << std::endl;return (n-1) + (n-2);}
    }int main()
    {std::packaged_task<int(int)> fib_task(&fib); std::cout << "starting task\n";//此时已经将package_task调用对象的执行返回值转交给future对象,所以后续//的线程执行由惰性赋值来触发。即当future的对象的共享状态尝试获取线程执行//结果的时候才进行线程执行,并返回结果。类似std::async的policy:std::launch::deferredauto result = fib_task.get_future(); std::thread t(std::move(fib_task), 40);std::cout << "waiting for task to finish...\n";std::cout << result.get() << '\n';std::cout << "task complete\n";t.join();
    }
    

    输出如下:

    starting task
    waiting for task to finish...
    fib  result 77
    77
    task complete
    
  • 析构函数~packaged_task()
    抛弃共享状态并销毁存储的任务对象,同 std::promise::~promise ,若在令共享状态就绪前抛弃它,则存储以 std::future_errc::broken_promise 为 error_code 的 std::future_error 异常

  • 赋值运算符
    packaged_task& operator=( const packaged_task& ) = delete
    复制赋值运算符被删除, std::packaged_task 仅可移动

  • std::packaged_task<R(Args...)>::get_future返回与 *this 共享同一共享状态的 future
    promise类一样,get_future 只能对每个 packaged_task 调用一次
    get_future成员出现异常的情况如下:

    • 已通过调用 get_future 取得共享状态。设置 error_category 为 future_already_retrieved
    • *this 无共享状态。设置 error_category 为 no_state
  • std::packaged_task<R(Args...)>::make_ready_at_thread_exit成员函数
    以转发的 args 为参数调用存储的任务。任务返回值或任何抛出的异常被存储于 *this 的共享状态。

    仅在当前线程退出,并销毁所有线程局域存储期对象后,才令共享状态就绪
    代码如下

    #include <future>
    #include <iostream>
    #include <chrono>
    #include <thread>
    #include <functional>
    #include <utility>void worker(std::future<void>& output)
    {std::packaged_task<void(bool&)> my_task{ [](bool& done) { done=true; } };auto result = my_task.get_future();bool done = false;//根据打印已经可以看到,此时已经执行了package_task的线程内容//但是共享状态到函数作用域结束之前并未就绪my_task.make_ready_at_thread_exit(done); // 立即执行任务std::cout << "worker: done = " << std::boolalpha << done << std::endl;auto status = result.wait_for(std::chrono::seconds(0));if (status == std::future_status::timeout)std::cout << "worker: result is not ready yet" << std::endl;output = std::move(result);
    }int main()
    {std::future<void> result;std::thread{worker, std::ref(result)}.join();//等到线程函数返回结果,且future对象就绪之后,可以看到打印状态变为就绪auto status = result.wait_for(std::chrono::seconds(0));if (status == std::future_status::ready)std::cout << "main: result is ready" << std::endl;
    }
    

总结

综上对package_task的描述,我们可以看到package_task模版类就像promise一样可以被异步调用,并且将调用对象执行的结果封装在future的共享状态中,来让调用者获取。同时package_task的调用者获取调用对象的执行结果过程就像async的惰性求值策略,当调用者想要获取调用对象的执行结果时才开始执行调用对象。

package_task的优势更多是它能够初始化所有的可调用对象,并且支持对该调用对象的异步访问机制。
promise更多的优势是线程之间的变量的传递,同时返回future类的共享状态。同时它也能够支持多种共享状态的访问机制,惰性求值/立即执行。

所以C++多线程的几个异步操作promiseasyncpackage_task都可以进行线程之间的异步操作,希望以此笔记在今后多线程编程中各持所需进行学习。

相关文章:

ICE BOX 配置,使用----第一篇

一 理论部分 (1) 为什么要使用icebox? icebox server代替了通常的server. icebox是为了方便集中管理多个ice服务而建立的。 它通过使用icebox服务器&#xff0c;把ice服务注册进去&#xff0c;从而建立联系。 所以它除了建立传统的ice服务器&#xff0c;ice客户端&#xff0c;…

测试打桩_DNF:CEO实测旭旭宝宝红眼,打桩高达2494E,伤害超越狂人剑魂

对于红眼这个职业&#xff0c;旭旭宝宝倾注了太多的心血&#xff0c;耗资几千万打造而成。虽然&#xff0c;作为固伤职业&#xff0c;在伤害方面&#xff0c;不及剑魂和剑帝这类百分比&#xff0c;但因人数颇多&#xff0c;从而被广泛关注。而今&#xff0c;旭旭宝宝的红眼&…

122112_1452_Word1

122112_1452_Word1转载于:https://www.cnblogs.com/joshuali/archive/2013/01/11/4339303.html

C++ 多线程:时间控制

C多线程库中的各个子库都有各自的时间控制方式&#xff0c;依此来进行多线程程序运行中cpu资源的精确控制。 使用std::chrono时间库可以提供微妙、毫秒、秒及以上的时间取用,并且能够获取当前系统时间。 如下代码 #include <iostream> #include <fstream> #inclu…

array用法 numpy_NumPy总结(基础用法)

numpy可以说是Python运用于人工智能和科学计算的一个重要基础&#xff0c;近段时间恰好学习了numpy&#xff0c;pandas&#xff0c;sklearn等一些Python机器学习和科学计算库&#xff0c;因此在此总结一下常用的用法。引入numpy库的方式&#xff1a;import numpy as np1、numpy…

python 字符串 转 dict

比直接eval更好的方法>>>import ast >>>ast.literal_eval("{muffin : lolz, foo : kitty}") {muffin:lolz,foo:kitty} 用 json 遇到问题&#xff1a; >>> import json json.loads({"x": 1,"y":2}) {uy: 2, ux: 1…

rhino-java中调用javascript

2019独角兽企业重金招聘Python工程师标准>>> 在有些情况下需要在java里面执行javascript&#xff0c;这时rhino就可以帮忙了。mozilla的一个开源产品。 官网https://developer.mozilla.org/en-US/docs/Rhino 之前的一篇博客http://my.oschina.net/yybear/blog/101…

HDU 2566 统计硬币

统计硬币 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 9633 Accepted Submission(s): 6505 Problem Description 假设一堆由1分、2分、5分组成的n个硬币总面值为m分&#xff0c;求一共有多少种可能的组合方式&…

linux C 多线程编程

文章目录多线程的一些小知识&#xff1a;1创建线程 pthread_create2线程挂起 pthread_join3线程终止 pthread_exit4线程分离 pthread_detach5线程取消 pthread_cancel线程同步 pthread_mutex_t互斥变量我们在写linux的服务的时候&#xff0c;经常会用到linux的多线程技术以提高…

JavaSE replaceAll 方法

private String srcStr "index\\.php\\?action";//要替换的原字符串 private String destStr "index.php?<{\\$LANGUAGE_TYPE}>action";//目的字符串 注意.和?都要转义&#xff0c;因此需要在前面添加两个反斜杠。 关于第二个参数&#xff0c;$…

elementui datetimepicker 移动端_在 Gitee 收获 2.5K Star,前后端分离的 RuoYi 它来了

作为 2019 年 Gitee 上最受欢迎的开源项目&#xff0c;权限管理系统 RuoYi 已经在 Gitee 上获得了超过 11K 的 Star。 这次作者若依推出了基于 SpringBoot Vue Element UI 的前后端分离版本的 RuoYi-Vue&#xff0c;方便有前后端分离开发需求的同学使用。项目名称&#xff1a…

用MyEclipse开发Spring入门

1 新建一个项目 File----->New ----->Project 在出现的对话框中选择 MyEclipse 下的 Web Project&#xff0c;在Project Name 输入mySpring1&#xff0c;其他的选项默认&#xff0c;再点Finish完成&#xff1b; 2 加入Spring 包 在myspring1 项目上点右键&#xff0c;选…

带你轻而易举的学习python——八皇后问题

首先我们来看一下这个著名的八皇后问题 八皇后问题&#xff1a;在88格的国际象棋上摆放八个皇后&#xff0c;使其不能互相攻击&#xff0c;即任意两个皇后都不能处于同一行、同一列或同一斜线上&#xff0c;问有多少种摆法。 在这个问题提出之后人们又将它扩展到了nn格的棋盘摆…

ubuntu18.04.1内核升级至5.0.0-25版本

ubuntu18.04操作系统版本先已支持在线的内核版本升级&#xff0c;到目前为止18.04发布版已经拥有三个小版本了1,2,3。 其中18.04.01和18.04.03版本&#xff0c;安装好之后默认的是4.15内核版本&#xff0c;但是默认支持在线安装4.18和5.0.0内核版本。 具体升级步骤如下&#x…

输出n行杨辉三角数

1 /*2 输出n行杨辉三角数 3 输入n&#xff0c;n是1&#xff5e;100之间的整数 4 */5 #include<stdio.h>6 int main()7 {8 int a[100],b[100];9 int i,j; 10 int n; 11 scanf("%d",&n); 12 if(n1) 13 { 14 printf("1\…

怎么扫描_打印机上扫描仪怎么用 打印机上扫描仪使用及添加方法

打印机是生活中常用的打印设备&#xff0c;主要用于连接 电脑 打印电脑上的文件&#xff0c;方便办公。对于第一次使用打印机的朋友可能还不是很熟悉如何使用&#xff0c;比如打印机上 扫描仪 怎么用&#xff1f;怎么添加打印机扫描仪&#xff1f;下面小编就来为大家介绍下吧。…

java 调用webservice的各种方法总结

http://www.blogjava.net/zjhiphop/archive/2009/04/29/webservice.html 现在webservice加xml技术已经逐渐成熟&#xff0c;但要真正要用起来还需时日!! 由于毕业设计缘故&#xff0c;我看了很多关于webservice方面的知识&#xff0c;今天和大家一起来研究研究webservice的…

vc++图像保存,重绘

新建mfc应用程序&#xff0c;单文档 增加绘图 分别增加命令响应 添加成员变量UINIT 图形可以运行&#xff0c;如何保存呢&#xff1f;&#xff08;一个集合类&#xff0c;CPtArt&#xff09; 用一个类的对象来保存一个图形的三个要素 所以插入一个新的类&#xff08;通常的类&a…

linux 进程内存分布及 堆分配和栈分配的特点

文章目录进程内存空间分布size命令查看内存分布堆方式内存分配和栈方式内存分配比较使用stap 深入追踪malloc逻辑进程内存空间分布 一个程序的内存空间主要如下&#xff1a; 代码段(text segment)&#xff1a;只读权限&#xff1b;常是指用来存放程序执行代码的一块内存区域&…

echarts 坐标自适应_echarts 同一页面,多个图表 页面大小自适应

// 路径配置require.config({paths: {echarts: ./js}});// 使用require([echarts,echarts/chart/line, // 折线图echarts/chart/bar // 柱状图],function (ec) {var myChart ec.init(document.getElementByIdx_x(main));var myChartx ec.init(document.getElementByIdx_x(main…

opencv——pcb上寻找mark点(拟合椭圆的方法)

#include "stdafx.h" // FitCircle.cpp : 定义控制台应用程序的入口#include "cv.h" #include "highgui.h" #include "cxcore.h" #include "cvaux.h" #include <iostream>using namespace cv; using namespace std; v…

bit,Byte、KB、MB、GB、TB、PB、EB之间的关系

计算机存储信息的最小单位&#xff0c;称之为位&#xff08;bit&#xff09;&#xff0c;音译比特&#xff0c;二进制的一个“0”或一个“1”叫一位&#xff1b;计算机存储容量基本单位是字节&#xff08;Byte&#xff09;&#xff0c;音译为拜特&#xff0c;8个二进制位组成1个…

echarts 点亮中国插件研究

echarts 真的是个神奇的东西&#xff0c;最近做了一个需要点亮中国的移动端项目&#xff0c;前期就怎样点亮中国做了调研&#xff0c;发现微博当初炫酷的点亮效果就是用echarts做的&#xff0c;于是研究了一下。 一连研究了一堆demo&#xff0c;不管从官网还是GitHub上面&#…

linux进程间通信:无名管道 pipe

文章目录内核层实现结构通信原理特点使用函数声明使用实例单向通信双向通信编程注意事项管道中无数据时读操作会阻塞将管道的写端句柄关闭&#xff0c;不会影响读端数据读取管道中没有数据&#xff0c;写操作关闭则读操作会立即返回管道大小测试 64K管道发生写满阻塞&#xff0…

争吵所达到的效果要_悟空:不要害怕争吵,有时候争吵一些不喜欢的事情也能创造和谐...

悟空&#xff1a;八戒&#xff0c;你吃了早饭去把马喂了吧。八戒&#xff1a;好的。悟空&#xff1a;喂了马你去看看我们午饭可以吃什么&#xff0c;如果有需要提前做预备的什么事儿&#xff0c;你知道该怎么做吧&#xff1f;八戒&#xff1a;好的。悟空&#xff1a;昨天&#…

Log4j日志管理的用法

参考网址&#xff1a; http://www.blogjava.net/314508313/archive/2011/11/14/363653.html http://www.cnblogs.com/likwo/archive/2010/09/01/1814994.html http://fanqiang.chinaunix.net/app/other/2006-06-22/4640.shtml http://www.blogjava.net/rickhunter/articles/281…

多线程实现生产者消费者模型

首先是一个仓库接口&#xff0c;该接口规定的仓库大小&#xff0c;仓库的存取方法&#xff0c;如下所示 1 package pers.lan.jc.pc;2 3 /**4 * author lan [1728209643qq.com]5 * create 2018-11-27 15:596 * desc 仓库7 */8 public interface Repertory<T> {9 10 …

再记一次ceph object unfound的艰辛历程

文章目录先说问题&#xff1a;再说解决尝试1&#xff1a;尝试2(该尝试建议先在自己环境搭配对应业务测试通过后再现场尝试)&#xff1a;感谢 学无止境996同学的陪伴和vigourtyy美丽女友的支持&#xff0c;直到这个解决问题的深夜先说问题&#xff1a; ceph 12.2.1生产环境&…

2014-01-04 SQL练习

目标数据库 250,czzznew/czzznew *关于执行计划&#xff1a;在PL/SQL选中查询的语句后&#xff0c;按下F5即可&#xff0c;其中Cost列表示当前操作的代价&#xff08;消耗&#xff09;&#xff0c;值越大代表性能越差 t_rkxx表 (1):用2种以上方法查出xm(姓名)为test或者Test的人…

多重集表示合json数据_计数DP(划分数,多重集组合数)

划分数&#xff1a;把n个无区别的物品划分成不超过m组。 dp[i][j]j的i划分的总数。 dp[i[j]dp[i][j-i]dp[i-1][j] 即&#xff1a;将j个物品分成i份&#xff0c;有两种情况&#xff1a;每份划分都大于等于1 dp[i][j-i]; 存在有一份以上用0划分dp[i-1][j]int main(){int n,m;cin&…