如果没有这样做,函数如何在新线程上“好像”运行?

问题描述 投票:19回答:7

根据C ++标准的[futures.async] / 3 bullet 1,当函数f通过std::async启动策略传递给std::launch::async时,f将运行“就像在新的执行线程中”。

鉴于f可以执行任何操作,包括无限循环和永久阻塞,实现如何提供f在其自己的线程上运行而不实际在其自己的线程上运行它的行为?也就是说,一个实现如何利用标准提供的“仿佛”摆动空间?

c++ multithreading c++11 stdasync
7个回答
6
投票

看看C ++ refs看起来像herehere,似乎“似乎”的目标是让图书馆实施者有一定程度的自由。例如,它说

好像由std :: thread(std :: forward(f),std :: forward(args)...)生成,除非函数f返回值或抛出异常,它将存储在共享状态中可以通过std :: future访问异步返回给调用者。

在第一个来源,和

好像一个线程对象是用fn和args作为参数构造的,并且访问返回的future的共享状态会加入它

在第二。所以它看起来像std::thread的行为类似,但可能以不同的方式实现。这很有趣,因为你在这里引用的执行线程可以与std::thread区分开来。尽管如此,似乎两个消息来源都明白了这种方式。

另一种选择可能是,如François Andrieux所建议的那样,允许使用线程池,如第一个源中所示:

模板函数async异步运行函数f(可能在一个单独的线程中,它可能是线程池的一部分)


5
投票

此解决方案的优势在于您在多线程世界中针对特定角色进行了优化实施。由于我参与了软件更新程序,我将使用这样的例子。出于优化原因,您可以致电:

std::thread::hardware_concurrency();

您将收到:

返回实现支持的并发线程数。

假设您的结果相等4.您希望并行执行更新。主要线程是监视期货清单(左边3个),不时检查是否完成,如果完成,则从待办事项列表中执行下一个操作。例如,如果您要更新不同类型的存储器,例如1-FileSystem,2-EEPROM,3-NOR存储器或类似的东西,那么利润就是这样。没有延迟检查循环没有利润,所以你想在检查之间给第4个线程一个任务。您正在编写正在挖掘比特币50毫秒的函数:)并且您在检查之间将其触发为延迟。

然后如你所说,我们有:

标准提供的“仿佛”摆动空间的优势


5
投票

有些方法我可以想到f可以在新线程上运行“好像”而不实际这样做,如果f实际上不使用与其他线程共享的任何状态;然后实现可以作为一个单独的进程运行它(因为它不需要共享内存空间)它也可以只在另一个函数调用上在主线程上运行它(如果它可以证明f没有阻塞或具有可观察性以这种方式运行会产生不同的副作用)。它也可以安排在现有(但空闲)的线程(线程池)上运行。

如果你想要愚蠢,我想你也可以考虑不运行f的概念,因为无法保证何时将新的线程安排为由操作系统运行,所以一个邪恶的实现可能只是说操作系统从不调度除主线程之外的任何线程,因此根本不运行f等同于在新线程上调度它。当然这是愚蠢/愚蠢的,没有理智的实现会做到这一点 - 但理论上语言允许这样一个退化的实现(我认为)。


2
投票

AFAIK C ++运行时能够管理一些内部(或专用)线程,区别于标准线程。

我的猜测(我还在学习C ++的高级功能)是,使用std::launch::async标志,std::async()将在一个新的内部线程中启动f

你可以使用f在一个新的标准线程中启动std::thread。在这种情况下,异常将在被调用的线程上处理,主代码必须获取f的返回值。

使用内部线程,返回值和最终异常存储在std::future中,由std::async()返回并在线程之间共享。

所以“好像”代表“好像我用f发射std::thread,但我不必”。但可以肯定的是,f将在一个新线程上运行。

要回答有关实现的问题,一旦运行时已经实现了标准线程,那么只需要将它们专门用于特定用途。另见execution policy for algorithms that support parallelization


2
投票

我看到“f将运行”的主要思想,好像在新的执行线程中“”是f将异步运行。是否应该是新线程或其他东西是实现细节。


1
投票

没有Thread的唯一解决方案,我能想到的是昨天的'Time-Slicing,这是一种多任务处理的形式。这些功能必须是可重入的。在这种情况下,每个函数都将运行,就好像它们位于不同的线程上一样,尽管它们实际上是在单线程上。


0
投票

在文档中,它在那里说,

模板函数async异步运行函数f(可能在一个单独的线程中,它可能是线程池的一部分)并返回一个最终将保存该函数调用结果的std :: future。

http://en.cppreference.com/w/cpp/thread/async

© www.soinside.com 2019 - 2024. All rights reserved.