gpt4 book ai didi

multithreading - Stroustrup指的是std::async的什么限制?

转载 作者:行者123 更新时间:2023-12-03 14:21:32 25 4
gpt4 key购买 nike

Bjarne Stroustrup在他的书《 C++编程语言》(第4版)的“教程”第5.3.5.3章中,写了std::async函数。

There is an obvious limitation: Don't even think of using async() for tasks that share resources needing locking – with async() you don't even know how many threads will be used because that's up to async() to decide based on what it knows about the system resources available at the time of a call.



the C++11-FAQ on his website中可以找到类似的建议。

“Simple” is the most important aspect of the async()/future design; futures can also be used with threads in general, but don't even think of using async() to launch tasks that do I/O, manipulates mutexes, or in other ways interact with other tasks.



有趣的是,当他在其书的第42.4.6节中更详细地介绍C++ 11的并发功能时,他没有详细说明这一限制。更有趣的是,在本章中,他实际上是继续进行(与他网站上的陈述进行比较):

A simple and realistic use of async() would be to spawn a task to collect input from a user.



The documentation of async on cppreference.com 完全没有提及任何此类限制。

在阅读了导致最终形式的C++ 11标准的一些建议和讨论之后(不幸的是,我没有这种方式),我了解到 async很晚才被纳入C++ 11标准中,并且存在一个很多讨论该功能应该有多强大。特别是,我发现 Async Tasks in C++11: Not Quite There Yet by Bartosz Milewski文章很好地总结了实现 async时必须考虑的问题。

但是,所有讨论的问题都与 thread_local变量有关,如果线程被回收,这些变量不会被破坏;如果线程切换其任务中间 Action 并且两个任务分别持有 mutexrecursive_mutex,则伪造死锁或数据访问冲突等。这些是该功能的实现者所关心的严重问题,但是如果我理解正确,那么 async的当前规范要求通过在调用者的线程上执行任务或就像为该任务创建了新线程一样,对用户隐藏所有这些详细信息。

所以我的问题是: 我不能与手动使用async进行的thread一起使用,该限制的原因是什么?

例如,下面的程序有什么问题吗?

#include <future>
#include <iostream>
#include <mutex>
#include <vector>

static int tally {};
static std::mutex tally_mutex {};

static void
do_work(const int amount)
{
for (int i = 0; i < amount; ++i)
{
// Might do something actually useful...
const std::unique_lock<std::mutex> lock {tally_mutex};
tally += 1;
}
}

int
main()
{
constexpr int concurrency {10};
constexpr int amount {1000000};
std::vector<std::future<void>> futures {};
for (int t = 0; t < concurrency; ++t)
futures.push_back(std::async(do_work, amount / concurrency));
for (auto& future : futures)
future.get();
std::cout << tally << std::endl;
}

显然,如果运行时决定在主线程上调度所有任务,那么我们将无缘无故地一遍又一遍地获取互斥体。但是,尽管这可能效率不高,但这并不是不正确的。

最佳答案

std::async的“问题”是默认情况下您不知道它是否启动线程。如果您的函数需要在单独的线程上运行,那么这是一个问题,因为您的函数可能要等到调用get()或wait()后才能运行。
您可以传递std::launch::async来确保函数在其自己的线程上启动,就像无法分离BG e的std::thread一样。

关于multithreading - Stroustrup指的是std::async的什么限制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26372904/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com