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

时间:2018-05-07 19:20:00

标签: c++ multithreading c++11 stdasync

C ++标准的每个[futures.async] / 3项目1,当函数f通过std::async启动政策传递给std::launch::async时,f将运行“好像在一个新的执行线程中”。

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

6 个答案:

答案 0 :(得分:6)

在C ++引用中看herehere似乎,“似乎”的目标是让库实现者有一定程度的自由。例如,它说

  

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

在第一个来源中,

  

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

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

正如François Andrieux所建议的那样,另一个选项可能允许使用threadpool,如第一个来源所示:

  

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

答案 1 :(得分:5)

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

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

答案 2 :(得分:2)

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

我的猜测(我还在学习C ++的高级功能)是,使用std::launch::async标记,std::async()将在新的内部<中启动f / strong> thread。

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

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

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

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

答案 3 :(得分:2)

我认为“f的主要思想将会运行”,好像在新的执行线程中“” f 将异步运行。是否应该是新线程或其他什么是实现细节。

答案 4 :(得分:1)

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

答案 5 :(得分:0)

在文档中,它在那里说,

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

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