问题标签 [c++-coroutine]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - VS2015 C++协程:promise.get_return_object()返回类型和协程返回类型
我对 Coroutines TS 的 Visual Studio 2015 实现有疑问。 P0057r5工作文件指出协程的行为就好像它的主体是:
(§ 8.4.4\3) 并且当协程返回到其调用者时,返回值就像是由语句产生的一样return gro;
(§ 8.4.4\5)
请注意,结果p.get_return_object()
存储在具有auto
推导类型的变量中。
让协程返回类型 beA
和promise.get_return_object()
返回类型 be B
。根据上面提到的 P0057r5 变量gro
应该有类型B
(由 推导auto
),并且类型的对象A
应该gro
在协程返回其调用者时构造(例如,使用转换运算符 in或in的B
隐式构造函数)。B
A
在当前的 Visual Studio 实现中(编译器版本字符串:“Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x86”)转换是在被调用之后p.initial_suspend()
和之前完成的,F'
就好像gro
类型被设置为匹配协程的返回类型 ( A
)而不是promise.get_return_object()
( B
) 的返回类型。
我错过了什么还是这是一个错误?
最小示例(使用 /await 编译):
输出:
c++ - 恢复 final_suspend 会导致错误,而不是破坏协程
James McNellis 在他的演讲“C++ 协程简介”(https://youtu.be/ZTqHjjm86Bw?t=1898)中说:
协程在以下情况下被销毁:
- final_suspend 恢复,
- coroutine_handle<>::destroy() 被调用,
以先发生者为准。
在我的测试中,我看到(VS 2015,VS 2017 RC),恢复在 final_suspend 上暂停的协程反而会导致错误:
Awaits2017.exe 中 0x010B9EDD 处未处理的异常:RangeChecks 检测代码检测到超出范围的数组访问。发生了
有什么想法可能会在这里发生吗?
c++ - C++1z协程线程上下文和协程调度
根据这个最新的 C++ TS:http ://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4628.pdf ,并基于对 C# async/await 语言支持的理解,我想知道 C++ 协程的“执行上下文”(从 C# 借用的术语)是什么?
我在 Visual C++ 2017 RC 中的简单测试代码显示协程似乎总是在线程池线程上执行,并且应用程序开发人员几乎无法控制协程可以在哪个线程上下文上执行 - 例如,应用程序是否可以强制所有协程(编译器生成的状态机代码)仅在主线程上执行,不涉及任何线程池线程?
在 C# 中,SynchronizationContext 是一种指定将发布和执行所有协程“半”(编译器生成的状态机代码)的“上下文”的方法,如本文所示:https ://blogs.msdn.microsoft.com /pfxteam/2012/01/20/await-synchronizationcontext-and-console-apps/,而当前 Visual C++ 2017 RC 中的协程实现似乎总是依赖于并发运行时,默认情况下在线程池线程。用户应用程序是否可以使用类似的同步上下文概念将协程执行绑定到特定线程?
此外,在 Visual C++ 2017 RC 中实现的协程的当前默认“调度程序”行为是什么?即 1) 如何准确指定等待条件?2)当等待条件满足时,谁调用挂起协程的“下半部分”?
我对 C# 中的任务调度的(天真)猜测是,C# 纯粹通过任务延续来“实现”等待条件 - 等待条件由 TaskCompletionSource 拥有的任务合成,并且任何需要等待的代码逻辑都将被链接为因此,如果满足等待条件,例如,如果从低级网络处理程序接收到完整消息,它会执行 TaskCompletionSource.SetValue,将底层任务转换为完成状态,有效地允许链接的继续逻辑开始执行(将任务从先前创建的状态置于就绪状态/列表) - 在 C++ 协程中,我推测 std::future 和 std::promise 将用作类似的机制(std::future 是任务,而std::promise 是 TaskCompletionSource,并且用法也惊人地相似!) - C++协程调度程序(如果有的话)是否依赖于一些类似的机制来执行行为?
[编辑]:在做了一些进一步的研究之后,我能够编写一个非常简单但非常强大的抽象,称为 awaitable,它支持单线程和协作多任务,并具有一个简单的基于 thread_local 的调度程序,它可以在根协程的线程上执行协程已启动。代码可以从这个 github repo 中找到:https ://github.com/llint/Awaitable
Awaitable 是可组合的,它在嵌套级别保持正确的调用顺序,并且它具有原始屈服、定时等待和从其他地方设置就绪的特点,并且可以从中派生出非常复杂的使用模式(例如无限循环协程,它只当某些事件发生时被唤醒),编程模型紧密遵循基于 C# 任务的异步/等待模式。请随时提供您的反馈。
c++ - co_await 似乎不是最理想的?
我有一个异步功能
我想在无堆栈协程中使用它,所以我写
然后我可以像这样使用它:
并且编译器会将其重写为:
有了这个,协程将保留a_
, b_
,并且c_
当它被暂停时,它只需要保留它们直到我们coroutine_handle
进入await_suspend(h)
。
(顺便说一句,我不确定我是否可以在此处保留对论点的引用。)
coroutine_handle
如果包装函数可以直接作为参数获取,效率会更高。
这可能是一个隐含的论点:
或者它可能是一个特殊的关键字参数:
我在这里错过了什么吗?(其他的开销不是那么大。)
c++ - 我可以在 await_suspend 期间调用 coroutine_handle::resume 吗?
考虑以下代码:
这里worker_thread
可以h.resume();
在协程仍在执行时await_suspend
或在协程之间await_suspend()
和之间调用return
。
Coroutines TS说resume
只有在协程挂起时才能调用。
执行期间是否被视为暂停await_suspend
?
visual-c++ - 没有返回语句的非无效协程
我正在尝试围绕 C++ 协程功能展开思考。我阅读了 Kenny 的文章 ( C++ - Introducing C++/WinRT ) 并尝试观看此演示文稿,CppCon 2016:James McNellis “C++ 协程简介”。我一直看到没有某种形式的 return 语句的非 void“函数”。作为一个例子,请参阅 Kenny 文章中的以下代码示例。PrintFeedAsync函数/协程具有IAsyncAction返回类型,但定义中没有返回语句。有人能解释一下这是如何工作的吗?
c++ - C++嵌套协程破坏问题
我正在试验 clang-5 及其协程 TS 实现。我正在尝试将它与 boost asio 一起使用,但遇到问题,似乎我的协程堆栈框架被破坏了两次,但我无法弄清楚我做错了什么。
这是我的简化复制场景:
它生成以下输出:
如您所见,asioConnect 函数中的 RaiiCheck 对象被破坏了两次。
asioConnect 函数内的 Future 对象具有地址为 0x7fbbeed03d50 的 coroutine_handle。当这个协程在 s.async_connect 完成回调中恢复时,RaiiCheck 对象第一次被销毁。然后我看到调用了 return_void 函数,它恢复了父协程,这似乎再次恢复了内部协程,从而导致 RaiiCheck 对象的另一次破坏。
它似乎与我的协程嵌套有关,因为如果我 co_await 直接在 async_connect 调用上而不是将 async_connect 调用放在另一个协程中,它就可以工作。
非常感谢任何解决此问题的提示。
c++ - 包含在协程中的 boost asio 计时器导致 clang-5.0 上的 SEGFAULT
以下代码会在启用协程支持的 clang-5.0 上导致 SEGFAULT。你可以在这里在线运行代码: wandbox 编译代码
我正在使用编译器选项:
当我在 GDB 下运行它时,它在 coro.resume() 之后的 async_await 中出现 SEGFAULTs;叫做。await_resume 函数永远不会到达。我希望这是一个对象生命周期问题。几乎相同的代码在 MSVC 2017 下编译和运行,没有任何问题。
程序的输出是:
源代码:
c++-coroutine - 有没有一个很好的协同程序现实世界的例子
目前我正在阅读很多关于协程的内容。虽然我认为我只部分了解了它们的作用(例如,允许返回一个函数并在某个时间点继续),但我真的不知道为什么要使用它们。我认为使用协程没有真正的好处。对我来说,这些东西在我看来就像带有额外步骤的 goto。有人可以给我一个很好的现实世界的例子,协程可以真正改善代码库吗?也许这有助于我理解这个概念。
c++ - 为什么C++20的coroutine_handle中提供了destroy()函数?
摘自n4680:
当控制流离开协程的末尾或调用与此协程关联的 std::experimental::coroutine_handle<P> 类型的对象的破坏成员函数 (18.11.2.4) 时,协程状态被破坏。在后一种情况下,在挂起点范围内的具有自动存储持续时间的对象以构造的相反顺序被销毁。通过调用非数组释放函数(3.7.4.2)释放协程状态的存储。如果为未挂起的协程调用destroy,则程序具有未定义的行为。
我的问题是:
现在协程状态会在执行离开协程时自动销毁,为什么在 中destroy()
提供显式函数coroutine_handle
?