6

为什么将协同程序(截至目前在 C++1z 的最新草案中)实现为核心语言功能(花哨的关键字和所有)而不是库扩展?

它们已经存在一些实现(Boost.Coroutine 等),根据我所读到的,其中一些可以独立于平台。为什么委员会决定将其融入核心语言本身?

我并不是说他们不应该,但 Bjarne Stroustrup 本人在一些谈话中(不知道是哪一个)提到应该尽可能在库中实现新功能,而不是触及核心语言。

那么这样做有充分的理由吗?有什么好处?

4

3 回答 3

8

虽然有协同程序的库实现,但它们往往有特定的限制。例如,库实现无法检测到协程挂起时需要维护哪些变量。可以解决这种需求,例如,通过以某种形式明确使用的变量。但是,当协程应该尽可能像普通函数一样运行时,应该可以定义局部变量。

我不认为 Boost 协程的任何实现者认为他们各自的库接口是理想的。虽然它是当前语言中可以实现的最好的,但整体使用可以得到改善。

于 2016-02-01T00:52:48.893 回答
7

在 CppCon 2015 上,来自 Microsoft 的 Gor Nishanov 提出 C++ Coroutines 可以是负开销抽象的论点。他演讲的论文在这里

如果您看一下他的示例,使用协程的能力简化了网络代码的控制流,并且在编译器级别实现时,可以为您提供更小的代码,其吞吐量是原始代码的两倍。他提出了真正的让步能力应该是 C++ 函数的一个特性的论点。

他们在 Visual Studio 2015 中有一个初始实现,因此您可以为您的用例尝试一下,看看它与 boost 实现的比较。不过,看起来他们仍在尝试确定是否会使用 Async/Yield 关键字,因此请密切关注标准的发展方向。

可在此处找到 C++ 的可恢复函数提案,并在此处找到更新。不幸的是,它没有进入 c++17,但现在是一个技术规范p0057r2。从好的方面来说,它们似乎在带有 -fcoroutines_ts 标志的 clang 和 Visual Studio 2015 Update 2 中得到支持。关键字也有一个 co_ 前缀。所以 co_await,co_yield 等。

协程是 golang、D、python、C# 中的内置功能,并将在新的 Javascript 标准(ECMA6)中。如果 C++ 提出更高效的实现,我想知道它是否会取代 golang 的采用。

于 2016-02-09T19:40:36.790 回答
3

C++1z 中的可恢复函数支持无堆栈上下文切换,而 boost.coroutine(2) 提供堆栈上下文切换。

不同之处在于,通过堆栈上下文切换,在协程中调用的函数的堆栈帧在挂起上下文时保持不变,而子程序的堆栈帧在挂起可恢复的函数(C++1z)时被删除。

于 2016-02-15T07:16:00.897 回答