- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
基于以下内容,看起来 C++20 中的协程将是无堆栈的。
https://en.cppreference.com/w/cpp/language/coroutines
我担心的原因有很多:
With a stackless coroutine, only the top-level routine may be suspended. Any routine called by that top-level routine may not itself suspend. This prohibits providing suspend/resume operations in routines within a general-purpose library.
coroutine state is allocated on the heap via non-array operator new. https://en.cppreference.com/w/cpp/language/coroutines
最佳答案
转发:当这篇文章只说“协程”时,我指的是协程的概念,而不是特定的 C++20 特性。在谈论这个功能时,我将其称为“co_await
”或“co_await 协程”。
关于动态分配
Cppreference 有时使用比标准更宽松的术语。 co_await
作为一项“需要”动态分配的功能;此分配是来自堆还是来自静态内存块或分配提供者的任何问题。这种分配可以在任意情况下省略,但由于标准没有说明它们,您仍然必须假设任何 co_await 协程都可以动态分配内存。
co_await 协程确实有机制让用户为协程的状态提供分配。因此,您可以将堆/空闲存储分配替换为您喜欢的任何特定内存池。co_await
作为一项功能经过精心设计,可以从任何 co_await
的使用点中删除冗长的内容。 - 对象和功能。 co_await
机械非常复杂和错综复杂,在几种类型的对象之间有很多相互作用。但是在暂停/恢复点,它总是看起来像 co_await <some expression>
.为可等待对象和 promise 添加分配器支持需要一些冗长的内容,但这种冗长的内容存在于使用这些东西的地方之外。
使用 alloca
对于协程将...非常不适合 co_await
的大多数用途.虽然围绕此功能的讨论试图隐藏它,但事实是 co_await
作为一项功能是为异步使用而设计的。这就是它的预期目的:停止函数的执行并安排该函数在潜在的另一个线程上恢复,然后将任何最终生成的值引导到一些可能与调用协程的代码有些距离的接收代码。alloca
不适用于该特定用例,因为允许/鼓励协程的调用者执行任何操作,以便其他线程可以生成该值。 alloca
分配的空间因此将不再存在,这对存在于其中的协程有点不利。
还要注意,这种情况下的分配性能通常会因其他考虑而相形见绌:线程调度、互斥锁和其他东西通常需要正确调度协程的恢复,更不用说从任何异步获取值所需的时间过程正在提供它。因此,在这种情况下,需要动态分配的事实并不是真正的重要考虑因素。
现在,有些情况下就地分配是合适的。生成器用例适用于您想要暂停函数并返回一个值,然后从函数停止的地方继续并可能返回一个新值的情况。在这些场景中,调用协程的函数的堆栈肯定仍然存在。co_await
支持这样的场景(虽然 co_yield
),但它以一种不太理想的方式这样做,至少在标准方面是这样。由于该功能是为上下挂起而设计的,因此将其转换为挂起协程会产生这种不需要动态的动态分配的效果。
这就是标准不需要动态分配的原因;如果编译器足够聪明,可以检测到生成器的使用模式,那么它可以删除动态分配,只在本地堆栈上分配空间。但同样,这是编译器可以做的,而不是必须做的。
在这种情况下,alloca
-基于分配将是适当的。
它是如何进入标准的
简而言之,它进入标准是因为它背后的人投入了工作,而替代方案背后的人没有。
任何协程的想法都是复杂的,并且总会有关于它们的可实现性的问题。例如,“resumeable functions”提案看起来很棒,我很想在标准中看到它。但实际上没有人在编译器中实现它。所以没有人可以证明这实际上是你可以做的事情。哦当然,这听起来可以实现,但这并不意味着它可以实现。
记住 what happened the last time “声音可实现”被用作采用功能的基础。
如果你不知道它可以被实现,你就不想标准化。如果你不知道它是否真的解决了预期的问题,你就不想标准化。
Gor Nishanov 和他在 Microsoft 的团队致力于实现 co_await
.他们这样做了多年,改进了他们的实现等。其他人在实际生产代码中使用了他们的实现,并且似乎对其功能非常满意。 Clang 甚至实现了它。尽管我个人不喜欢它,但不可否认的是co_await
是一个成熟的功能。
相比之下,一年前作为与 co_await
竞争的想法提出的“核心协程”替代方案。未能获得牵引力 in part because they were difficult to implement .这就是为什么co_await
被采用:因为它是人们想要的一种经过验证、成熟且可靠的工具,并且具有改进代码的能力。co_await
不适合所有人。就我个人而言,我可能不会经常使用它,因为对于我的用例来说,纤维工作得更好。但它非常适合它的特定用例:上下悬挂。
关于c++ - 无堆栈 C++20 协程有问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57163510/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!