C++ 多线程编程(三) 获取线程的返回值——future

这篇具有很好参考价值的文章主要介绍了C++ 多线程编程(三) 获取线程的返回值——future。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C++11标准库增加了获取线程返回值的方法,头文件为<future>,主要包括futurepromisepackaged_taskasync四个类。

那么,了解一下各个类的构成以及功能。

1 future

future是一个模板类,它是传输线程返回值(也称为共享状态)的媒介,也可以理解为线程返回的结果就安置在future中。

future 版本:C++11      头文件<future>
构造函数

1. future() noexcept;

默认构函数,是一个无效future,valid函数返回false.

2. future(future&& other) noexcept

移动构造函数,使用后other.valid()为false。

3. future(const future& other) = delete

禁用拷贝构造函数。

析构函数 ~future();
get

std::future<T>  T get();

获取共享状态,如果共享状态尚未就绪(比如线程未结束),则堵塞,等效于wait函数。

valid

bool valid() const noexcept;

判断future是否有效。无效future有三种情况:一是使用默认构造函数创建的;调用过移动构造函数;三是调用过get函数

wait

void wait() const;

获取共享状态,如果共享状态尚未就绪(比如线程未结束),则堵塞;阻塞结束之后,还需要继续调用get才能获取共享状态,此时get不再阻塞。

wait_for 设置最大阻塞时间
wait_until 设置最大阻塞时刻

跟多线程相关的类,大多都有一个特点,就是禁用拷贝构造函数,仅能使用移动构造函数。

单独使用future依然没有办法获取线程的返回值,必须与promise、packaged_task或者async搭配使用。而且,单独创建出来的future对象甚至都没有意义,必须从promise、packaged_task或者async中创建,才有意义。

2 promise

promise对象可以看做是future类的封装,它可以原子的修改future的共享状态。

promise C++ 11                  头文件: <future>
构造函数

1. promise();

默认构造函数,构造一个共享状态为空的 std::promise

2. promise(promise&& other) noexcept;

移动构造函数,用原属 other 的共享状态构造新的 std::promise 对象,使用移动语义。构造完毕后, other 无共享状态;

3. future(const future& other) = delete;

禁用拷贝构造函数。

get_future

std::future<T> get_future();

获取共享状态,返回一个future对象。

set_value 原子地存储 value 到共享状态,并令状态就绪(future::get结束阻塞)。
set_value_at_thread_exit 原子地存储 value 到共享状态,而不立即令状态就绪。在当前线程退出时,再令状态就绪。
#include <thread>
#include <future>
#include <iostream>

void fun1(std::promise<int> pro) {
    std::this_thread::sleep_for(std::chrono::seconds(3));
    pro.set_value(100);
    return;
};

int main()
{
    std::promise<int> pro;
    std::future<int> fut = pro.get_future();
    std::thread th(&fun1, std::move(pro));
    th.detach();
    std::cout << fut.get() << std::endl;
}

需要注意的一点是,future的模板类型与线程函数的返回类型无关。上边fun1函数的返回值为void,但是future类型为int。

3 packaged_task

packaged_task是一个类,它主要包含了一个future对象和一个任务,这个任务可以是函数、 lambda 表达式、 bind 表达式或其他函数对象。

packaged_task C++11                      头文件: <future>
构造函数

template<class F>

explicit packaged_task(F&& f);

f 是一个函数,也就是任务入口。

get_future

std::future<T> get_future();

获取共享状态,返回一个future对象。

()运算符

void operator()(ArgTypes...args);

args 为参数运行存储的任务;任务结束时,将返回值存储于共享状态,并令共享状态就绪。该函数会新开一个线程并以detach模式运行新线程。

#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();
}

输出:

C++ 多线程编程(三) 获取线程的返回值——future

 与promise不同的是,packaged_task任务的返回类型就是future的类型。

4 async

async是一个模板函数,它综合了前边promise和packaged_task的功能,一个函数就可以实现线程创建、任务执行、获取返回值等功能。

async的返回值是一个future对象,async所执行的任务完成后,会令共享状态进入就绪状态。文章来源地址https://www.toymoban.com/news/detail-434563.html

#include <thread>
#include <future>
#include <iostream>
#include <unistd.h>

int main()
{
    auto ff = std::async(std::launch::async, []{ sleep(2); return 2.3; }); 

    std::cout << ff.get() << std::endl;
}

到了这里,关于C++ 多线程编程(三) 获取线程的返回值——future的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++并发与多线程笔记八:async、future、packaged_task、promise

    本文接上文 C++并发与多线程笔记七:condition_variable、wait、notify_one/all 的内容,主要记录 async、future、packaged_task、promise 概念以及用法。 2.1 基本用法 std::async 是个函数模板,用来启动一个异步任务,启动一个异步任务后,它返回一个 std::future 类模板对象。 上述\\\"启动一个异步

    2023年04月13日
    浏览(38)
  • 【linux c多线程】线程的创建,线程信息的获取,获取线程返回值

    ​ 专栏内容 : 参天引擎内核架构 本专栏一起来聊聊参天引擎内核架构,以及如何实现多机的数据库节点的多读多写,与传统主备,MPP的区别,技术难点的分析,数据元数据同步,多主节点的情况下对故障容灾的支持。 手写数据库toadb 本专栏主要介绍如何从零开发,开发的

    2024年02月04日
    浏览(26)
  • Python 中从线程获取返回值

    这篇文章首先讨论了线程的基础知识,并提供了一个在Python中启动线程的代码示例。然后,我们将讨论一个在线程中获取函数返回值的代码。 线程是进程内的轻量级执行单元,具有自己的程序执行状态。一个进程可以运行多个线程以实现并发(有时也是并行)。 进程和线程

    2024年02月07日
    浏览(25)
  • 使用多线程执行任务,并获取返回结果,附异步实现

    这里创建了一个包含三个线程的固定线程池 线程池的介绍 根据主机情况实现自定义线程池: 也可以通过继承 ThreadPoolExecutor 类来实现一个自定义线程池工具类。ThreadPoolExecutor 是 Java 标准库中提供的一个线程池实现,通过继承它,我们可以实现自定义的线程池。 下面是一个继

    2024年02月16日
    浏览(29)
  • java多线程异步处理并获取处理后的返回值

    示例部分代码:

    2024年02月06日
    浏览(31)
  • C++并发编程:std::future、std::async、std::packaged_task与std::promise的深度探索

    1.1 并发编程的概念 (Concept of Concurrent Programming) 并发编程是一种计算机编程技术,其核心在于使程序能够处理多个任务同时进行。在单核处理器上,虽然任何给定的时间只能运行一个任务,但通过任务切换,可以创建出并发执行的效果。而在多核处理器上,可以真正同时处理

    2024年02月05日
    浏览(27)
  • C++学习笔记-第11单元 标准模板库介绍

    注:本部分内容主要来自中国大学MOOC北京邮电大学崔毅东的 《C++程序设计》课程。 注:94条 C++程序规范。   本单元重点是对标准模板库中的 顺序容器 、 关联容器 的使用,以及 如何创建迭代器以遍历容器 。在使用容器时要注意不同容器的实现方式对遍历、搜索、删除、

    2024年02月13日
    浏览(27)
  • JAVA学习-网络编程.Java11标准化的HTTP Client

            Java 11引入了标准化的HTTP Client,它提供了一种现代化、灵活且易于使用的方式来进行HTTP通信。下面是关于Java 11标准化的HTTP Client的概述以及与其他比较和高级应用的说明:         Java 11标准化的HTTP Client是一种替代HttpURLConnection的新的HTTP客户端库。它提供了更

    2024年04月09日
    浏览(27)
  • c++ 11标准模板(STL) std::vector (二)

    template     class T,     class Allocator = std::allocatorT class vector; (1) namespace pmr {     template class T     using vector = std::vectorT, std::pmr::polymorphic_allocatorT; } (2) (C++17 起) 1) std::vector 是封装动态数组的顺序容器。 2) std::pmr::vector 是使用多态分配器的模板别名。 元素相继存储,这意味着不

    2024年02月02日
    浏览(40)
  • C++学习笔记——C++ 新标准(C++11、C++14、C++17)引入的重要特性

    目录 1、简介 2.自动类型推导和初始化 示例代码 3.智能指针 示例代码 4.Lambda 表达式 示例代码 5.右值引用和移动语义 示例代码 6.并发编程支持 示例代码 7.其他特性 八、案例:实现一个简单的并发下载器 上一篇文章:     C++标准模板库(STL)是C++的一个重要组成部分,它提

    2024年01月19日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包