我正在阅读一篇关于使用 C++ 进行并发编程的文章( 链接)。 在本文中,作者展示了一段代码,std::async 在同一个线程中运行两个函数。 此外,当他将 std::future 与 std::async 一起使用时,它的行为再次不同,并使用独立线程运行所有函数。 为什么 async 表现得像那样并且它有这种不受控制的方式? 另外,如何开发具有此功能的真正并发程序? 这是可能的还是我应该错过它?

#1楼 票数:4 已采纳

我建议也阅读参考资料,在“注释”部分更好地解释了发生的情况

如果从 std::async 获得的 std::future 没有从引用移动或绑定到引用,则 std::future析构函数将在完整表达式的末尾阻塞直到异步操作完成[...]

或者换句话说std::async返回一个std::future 一旦返回的对象被销毁,它将等待它所代表的运行操作结束。 因此,如果您丢弃返回值,例如

std::async(xyz);

返回值的析构函数在返回后立即被调用,从而等待xyz的完成。

如果您保留返回值,例如

auto futureXyz = std::async(xyz);

它确实并行运行。 那是因为返回值被移动到变量futureXyz ,所以局部变量“拥有”并行执行函数。

我不会称其为“不受控制的行为”,这只是您出乎意料的事情,但它的定义很明确。

#2楼 票数:1

来自 std::async 上的 cppreference 文档:

...异步运行函数 f (可能在一个单独的线程中...)(粗体是我的)。

的std ::异步保证产卵一个单独的线程来执行指令,如果你需要一个单独的线程来确定使用的std ::线程 这将保证产生一个单独的线程,您可以使用 std::future、原子变量等与它通信。

示例代码:

std::mutex cout_lock;
auto thread = std::thread([]{
  std::lock_guard<mutex> lock(cout_lock);
  std::cout << "Hello world from thread!\n";
});

std::lock_guard<mutex> lock(cout_lock);
std::cout << "Hello world!\n";
thread.join();

请注意我上面的代码如何使用互斥锁,因为 cout 本质上不是线程安全的

  ask by translate from so

未解决问题?本站智能推荐:

2回复

是否有使用线程池的std::async实现?

标准函数std :: async : 模板函数async异步运行函数f(可能在单独的线程中,该线程可能是线程池的一部分),并返回std :: future,该变量最终将保存该函数调用的结果。 有两个启动策略std :: launch :: async和std :: launch ::
1回复

std::async如何工作:为什么它多次调用复制/移动?

基本上是标题 结果是 一个动作是将一个对象传递给一个 async,一个将它传递给 async 内部的函数,但另一个动作是做什么?
2回复

有没有办法在std::experimental::future中使用std::async?

注意:即使在C ++ 17中,以下内容也是非法的! C ++ 1z提供了两种类型的future : std::future std:experimental::future 但是, std::async仅返回std::future ,因此上面的代码是非法的。 如果std::
2回复

是std::map::end线程安全并且保证它对于同一个容器总是相同的吗?

我使用std::map并获得一个我可以使用的元素: http : //www.cplusplus.com/reference/map/map/ iterator find (const key_type& k); mapped_type& at (const key_t
2回复

POSIX线程,将多个参数传递给具有结构的函数

因此,我花了最后几个小时尝试使用google找出我的代码出了什么问题,但我无法弄清楚。 我是一名学生,刚开始学习线程等知识,所以这对我来说是全新的,我也不是很有经验。 谷歌(和这里)的答案通常是代码中一个特定问题的答案,我不知道该如何真正地工作。 这是我的代码的非常简化的版本:
2回复

std::thread最大并发线程数

我试图了解std::thread的一些基本概念,但我仍然对此并不自信。 潜在的问题是: 当我超过std::thread::hardware_concurrency()的值时,实际上发生了什么,就像我在下面所做的那样? 我知道该方法只是一个提示,但在这种情况下8应该是正确的。 我没有看
1回复

C++11线程修改std::list

我将发布我的代码,然后告诉您我在做什么。 我认为这段代码正在做的是在列表末尾添加10000个元素。 对于我们添加的每10个,启动一个(单个)线程,该线程将删除列表的前10个元素(在启动线程时)。 我不希望这会删除每个列表元素,我只是想看看在从开头删除元素的同时是否可以添加到列表的末尾。
1回复

为什么我的程序在1个线程上比在8个线程上运行更快?

请看下面的代码: 当我在并发版本上运行时(基本上在8个线程上运行,因为我的std::thread::hardware_concurrency();返回8) 输出为:处理花费: 8895404 nanoseconds 。 但是单线程选项的输出为: process took: 124 n