您是否需要存储 std::async 的 std::future 返回值?

2024-04-18

考虑以下代码:

#include <iostream>
#include <future>
#include <thread>
#include <chrono>

void func()
{
    std::async(std::launch::async, []{std::this_thread::sleep_for(std::chrono::milliseconds(1000)); });
}

int main()
{

    std::cout << "start " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "ms\n";
    func();
    std::cout << "stop  " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "ms\n";

    return 0;
}

outputs:

start 18737230ms
stop  18738230ms

我们可以看到1秒过去了func()返回。但是没有存储 std::futurestd::async(...);- IE。:auto f = std::async(...)

这似乎有效 - 但我想知道它的工作机制是什么。如果我有一个 std::future (在我的小例子中为 auto f ),那么当它超出范围时,它会整理线程 - 即等待 1 秒,然后线程在幕后被处理。

进一步测试:

int main() {

    std::cout << "start " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "ms\n";
    std::async(std::launch::async, []{std::this_thread::sleep_for(std::chrono::milliseconds(1000)); });
    std::cout << "stop1 " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "ms\n";
    auto f = std::async(std::launch::async, []{std::this_thread::sleep_for(std::chrono::milliseconds(1000)); });
    std::cout << "stop2 " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "ms\n";
    return 0;
}

gives:

start 4448133ms
stop1 4449133ms - 1 sec passed
stop2 4449133ms - almost no time passed

所以这表明存储未来意味着线程并行运行。不存储未来意味着线程似乎必须运行完成 - 我猜这是因为创建和销毁了临时未来?

所以我的结论是你不能只打电话std::async(...)如果您希望它并行运行(这就是重点),则无需存储 std::future - 即使您不打算使用 future。

嗯...我想我刚刚说服了自己答案! - 但我不是 100% 确定我的推理是正确的 - 希望我有......


If the std::future是通过创建的std::async,析构函数等待任务结束。这并不意味着任务不并行运行 - 它只是在变量范围末尾等待任务结束。然而它利用了std::async不存储std::future有点棘手,我通常建议将 future 存储在某个地方以避免令人讨厌的意外。看一看在关于页面std::future析构函数 https://en.cppreference.com/w/cpp/thread/future/%7Efuture(强调我的):

这些操作不会阻止共享状态变为就绪状态,但如果满足以下所有条件,则可能会阻止:共享状态是通过调用 std::async 创建的,共享状态尚未准备好,这是对共享状态的最后一次引用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

您是否需要存储 std::async 的 std::future 返回值? 的相关文章

  • 通过另一个列表更新列表(linq)

    我有类 Data 的对象列表 如下所示 class Data int code string name DateTime date update 我还有另一个课程列表 例如 class RefCodes int old code int n
  • 通过 SOAP 的 Gmt php 或 UTC C# 等效项

    is C DateTime UtcNow和 PHPdate c 是等价的 我怀疑 因为当我肥皂时 我得到了 C
  • 从另一个 FORM 中取回隐藏的 FORM

    我有两种形式Form1 and Form2 我正在打开Form2 from Form1 on button Click Form2 obj2 new Form2 this Visible false obj2 Show 然后我想回来Form
  • OpenGL缓冲区更新[重复]

    这个问题在这里已经有答案了 目前我正在编写一个模拟水的程序 以下是我所做的步骤 创建水面 平面 创建VAO 创建顶点缓冲区对象 在其中存储法线和顶点 将指针绑定到此 VBO 创建索引缓冲区对象 然后我使用 glDrawElements 渲染
  • 在 Mac OS X 上安装 libxml2 时出现问题

    我正在尝试在我的 Mac 操作系统 10 6 4 上安装 libxml2 我实际上正在尝试在 Python 中运行 Scrapy 脚本 这需要我安装 Twisted Zope 现在还需要安装 libxml2 我已经下载了最新版本 2 7 7
  • MSMQ接收和删除

    是否有任何选项可以在读取消息后将其从 MSMQ 中删除 比如 接收 删除可以作为原子操作运行吗 听起来您想查看下一条消息 然后在处理完成后接收它 Message message Queue Peek Queue ReceiveById me
  • 如何查明 .exe 是否正在 C++ 中运行?

    给定进程名称 例如 程序 exe C 标准库没有这样的支持 您需要一个操作系统 API 来执行此操作 如果这是 Windows 那么您将使用 CreateToolhelp32Snapshot 然后使用 Process32First 和 Pr
  • DataGridView 列中的数字文本框

    我有一个DataGridView 我想要它的第一列或任何所需的列 其中有textboxes在其中 成为NUMERIC ONLY 我目前正在使用这段代码 private void dataGridViewItems EditingContro
  • Nhibernate:连接表并从其他表获取单列

    我有以下表格 create table Users Id uniqueidentifier primary key InfoId uniqueidentifier not null unique Password nvarchar 255
  • C# Winforms Designer 无法打开,因为它无法在同一程序集中找到类型

    我收到以下错误 找不到类型 My Special UserControl 请确保引用包含此类型的程序集 如果此类型是您的开发项目的一部分 请确保已使用当前平台或任何 CPU 的设置成功构建该项目 但没有任何意义的是My Special Us
  • 判断串口是普通COM还是SPP

    我正在寻找一种方法来确定 COM 是标准 COM 还是 SPP COM 也称为 COM 设备的电缆替换蓝牙适配器 我有一个可以在 USB COM gt USB 和蓝牙下工作的设备 并且蓝牙接口可以与 SPP 一起工作 我目前正在使用Syst
  • C 类型命名约定,_t 或 ALLCAPS

    我一直想知道是否有任何命名约定 例如何时对类型使用全部大写以及何时追加 t 什么时候不使用任何东西 我知道当时 K R 发布了各种有关如何使用 C 的文档 但我找不到任何相关内容 在 C 标准库类型中 t看起来漂亮占主导地位 time t
  • “没有合适的默认构造函数可用”——为什么会调用默认构造函数?

    我已经查看了与此相关的其他一些问题 但我不明白为什么在我的情况下甚至应该调用默认构造函数 我可以只提供一个默认构造函数 但我想了解它为什么这样做以及它会产生什么影响 error C2512 CubeGeometry no appropria
  • 如何在新窗口中打开图像或pdf文件?

    我有一个 gridview 它包含文件名和文件路径 图像和 pdf 格式文件 其中我使用了模板字段 在该字段下放置了 1 个图像按钮 单击该图像按钮 即 查看 按钮 时 我想在新窗口中打开所选文件 这是我的代码 protected void
  • 如果在代码中添加元素,“FindName”将不起作用

    在 WPF 应用程序中 如果在 XAML 中声明 ContentControl
  • WinForms - 加载表单时如何使用 PaintEventArgs 运行函数?

    我试图理解图形 在 Graphics FromImage 文档中 它有这样的示例 private void FromImageImage PaintEventArgs e Create image Image imageFile Image
  • C++ 模板可以提供 N 个给定类的公共父类吗?

    我正在寻找一个 C 模板 它可以找到一组给定类的共同父级 例如 class Animal class Mammal public Animal class Fish public Animal class Cat public Mammal
  • 在 C 中使用 #define 没有任何价值

    If a define没有任何价值地使用 例如 define COMMAND SPI 默认值是0吗 不 它的评估结果为零 从字面上看 该符号被替换为空 然而 一旦你有了 define FOO 预处理器条件 ifdef FOO现在将是真的 另
  • MSVC编译器下使用最大成员初始化联合

    我正在尝试初始化一个LARGE INTEGER在 C 库中为 0 确切地说是 C 03 以前 初始化是 static LARGE INTEGER freq 0 在 MinGW 下它产生了一个警告 缺少成员 LARGE INTEGER Hig
  • 是否可以使用 Dapper 流式传输大型 SQL Server 数据库结果集?

    我需要从数据库返回大约 500K 行 请不要问为什么 然后 我需要将这些结果保存为 XML 更紧急 并将该文件通过 ftp 传输到某个神奇的地方 我还需要转换结果集中的每一行 现在 这就是我正在做的事情 TOP 100结果 使用 Dappe

随机推荐