何时更喜欢 lambda 而不是带有 std::async 的打包任务? [复制]

Posted

技术标签:

【中文标题】何时更喜欢 lambda 而不是带有 std::async 的打包任务? [复制]【英文标题】:when to prefer lambda over packaged task with std::async? [duplicate] 【发布时间】:2021-10-04 04:32:33 【问题描述】:

我有点困惑,什么时候需要将 packaged_task 传递给 std::async。当我可以直接传递带有参数的函数时,我真的需要 std::packaged_task 吗? 有什么东西只能通过打包任务而不是正常的功能方法来实现吗?

方法一:std::async 与 lambda 函数

std::future<int> result= std::async(std::launch::async, [](int m, int n)  return m + n; , 2, 4));

方法 2:std::async 与 packaged_task,

        auto f = [](int m, int n)  return m + n;;
        std::packaged_task<int(int,int)> task(f);
        std::future<int> result = task.get_future();
     
        std::async(std::launch::async, std::move(task), 2, 4);
        int ans = result.get();
        

我已经检查了答案,但没有一个给我合适的用例。看起来编码员可以使用这些方法中的任何一种,但是什么时候一个分数高于另一个?

【问题讨论】:

我的经验法则是:单个语句中的内容越多,认知负荷就越高。因此,我倾向于使用更小、更容易掌握顺序语句的代码,而不是将大量行为打包到单个语句中——因为它更易于代码审查和维护。我与一些持有相反观点的优秀开发人员一起工作,他们宁愿把所有东西都塞进一个声明中。编译器不在乎,优化器可以很好地优化任何一种风格。因此,请使用最适合您团队的方法。 @Eljay - 你的意思是它只是一个偏好问题,方法 1 和 2 之间没有其他区别吗? 对于std::async,您应该使用 lambdas。 std::packaged_task 不使用std::async @bolov - 你说“对 packaged_task 的调用是异步的”是什么意思?据我所知,为了异步运行打包任务,您需要通过 std::async 调用它。调用没有 std::async 的打包任务相当于一个普通的函数调用。 @Test "为了异步运行打包任务,您需要通过std::async" 调用它——我不这么认为。例如,在线程池中使用打包任务,其中您有固定数量的线程和打包任务的共享队列。然后线程只是从队列中获取任务并执行它们。这里不涉及async 【参考方案1】:

不需要std::packaged_task 替换为std::async

std::packaged_task 在您自己管理线程但仍需要带有std::future 的可调用包装器时很有用。这意味着拥有通过std::thread 或其他方式实现的工作线程或线程池。

std::packaged_task 做其他与异步任务相关的事情:

std::future 包装结果 转发时复制参数,而不是通过“通用引用”传递它们 确保只移动语义而不是可复制(lambdas 或 std::function 可以复制,std::packaged_task 不能)

【讨论】:

您能详细说明一下吗?我没有完全理解你的回答,因为它太技术性了,我无法清楚地理解。当您说“自己管理线程”时,您是什么意思?你是什​​么意思“但仍然希望有一部分任务管理由标准库来完成”? 详细说明

以上是关于何时更喜欢 lambda 而不是带有 std::async 的打包任务? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

何时更喜欢 JSON 而不是 XML?

您何时更喜欢 DateTime 而不是 DateTimeOffset

何时更喜欢 XAMPP 而不是 Linux、Apache、MySQL 和 PHP 的完整安装

何时使用函数模板而不是通用 lambda?

Rails Routes:带有身份验证块的更清晰的 if 语句

iOS Swift:闭包(回调)与委托,何时使用? [关闭]