在asio stackful协同程序中直接使用产卵是否安全
Is it safe to use spawn directly in an asio stackful coroutine?
当我使用spawn在协同程序中启动一个新的堆栈完整协同程序时,valgrind说很多都使用了未初始化的值(valgrind输出)。
然后我使用io_service.post调用一个处理程序,并在其中启动一个新的stackfull协程,一切似乎都很好。
我已经搜索并阅读了一些文档,但找不到关于如何在堆栈完整协程中安全地创建新的堆栈完整协程的信息。
这是代码:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/system_timer.hpp>
#include <chrono>
using namespace std;
int main()
{
auto use_post = false;
boost::asio::io_service io_service;
boost::asio::spawn(io_service,
[&io_service, &use_post](boost::asio::yield_context yield){
if(use_post){
io_service.post([&io_service]{
boost::asio::spawn(io_service, [&io_service](boost::asio::yield_context yield){
boost::asio::system_timer timer(io_service);
timer.expires_from_now(std::chrono::seconds(1));
timer.async_wait(yield);
cout << "Sleep 1 second" << endl;
});
});
}
else{
boost::asio::spawn(io_service, [&io_service](boost::asio::yield_context yield){
boost::asio::system_timer timer(io_service);
timer.expires_from_now(std::chrono::seconds(1));
timer.async_wait(yield);
cout << "Sleep 1 second" << endl;
});
}
boost::asio::system_timer timer(io_service);
timer.expires_from_now(std::chrono::seconds(2));
timer.async_wait(yield);
cout << "Sleep 2 seconds" << endl;
});
io_service.run();
return 0;
}
如果use_post
变量设置为true,则新的stackfull协同程序将通过post+spawn启动。
也许我没有仔细阅读这些文档,在Boost.Asio C++ Network Programming
、N4045
和boost asio文档中找不到任何有用的东西。
它是安全的。
Boost。Asio对Boost的一流支持。Coroutine是一个薄薄的外表,有两个显著的行为:
- 协程和恢复它的处理程序使用
strand
作为它们的执行上下文。这保证了协同程序在产生结果之前不会恢复 - 如果检测到没有可用的处理程序来恢复协程,Boost.Asio将阻止协程无限期暂停。当这种情况发生时,Boost.Asio将破坏协程,导致暂停的堆栈展开。有关详细信息,请参阅此答案
在上面的示例代码中,spawn(io_service&)
重载导致生成的协程具有自己的strand
。因此,如果多个线程正在运行io_service
,则每个协程都可以并行运行,但不能保证这样做。另一方面,如果使用spawn(yield_context)
重载,则新的协程将具有与调用协程相同的执行上下文(即strand
),从而阻止并行执行。
相关文章:
- 通过网络、跨平台传递std::变体是否安全
- 在类型和包装器之间reinterpret_cast是否安全<Type>?
- 跨 DLL 边界访问虚拟方法是否安全/可能?
- 静态 constexpr 类成员变量对多线程读取是否安全?
- 在函数结束后使用指向变量的指针是否安全?
- 逐字节删除 void* 是否安全?
- 在 RAII 构造中修改 RVO 值是否安全?
- 线程调用的函数对对象删除是否安全?
- 将对象的字节复制到数组并再次复制回来是否安全
- std::memmove在同一对象之间是否始终安全
- 使用枚举为数组编制索引是否安全?
- 返回从字符串文本创建的静态string_view是否安全?
- 在cstlib中将#include_next替换为#include是否安全
- 由并发无序映射查找线程调用的函数是否安全?
- 使用 c++ 原子时编写"y=++x"是否安全?
- 从另一个线程发出信号是否安全?
- 从其存储的回调中删除 std::函数是否安全
- 使用 std::vector::swap 方法在C++中交换两个不同的向量是否安全?
- 当我在C++中调用 struce 的只读静态成员时,线程是否安全
- 同时调用 ASIO 对象的 API 是否安全?