直接在asio堆栈式协程中使用spawn安全吗? [英] Is it safe to use spawn directly in an asio stackful coroutine?

查看:305
本文介绍了直接在asio堆栈式协程中使用spawn安全吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我使用spawn在协程中启动新的stackfull协程时,valgrind说很多使用未初始化的值( valgrind输出).

When I use spawn to start a new stackfull coroutine in a coroutine, valgrind says a lot of using uninitialised value(valgrind output).

然后我使用io_service.post调用处理程序,并在其中启动一个新的stackfull协程,一切似乎都很好.

Then I use io_service.post to invoke a handler,and start a new stackfull coroutine in it, every thing seems fine.

我已经搜索并阅读了一些文档,但是找不到有关如何在全栈协程中安全地创建新的全栈协程的信息.

I have searched and read some documents, but can't find something about how to create a new stackfull coroutine safely in a stackfull coroutine.

这是代码:

#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启动.

set true to use_post variable, new stackfull coroutine will be started by post + spawn.

也许我没有仔细阅读文档,在Boost.Asio C++ Network ProgrammingN4045和boost asio文档中找不到任何有用的东西.

Maybe I don't read the documents carefully, i can't find any thing usefull in Boost.Asio C++ Network Programming, N4045 and boost asio document.

推荐答案

这很安全.

Boost.Asio对Boost.Coroutine的一流支持是具有两个显着行为的薄外墙:

Boost.Asio's first-class support for Boost.Coroutine is a thin facade with two notable behaviors:

  • 协程和恢复它的处理程序使用答案.
  • A coroutine and handlers which resume it use a strand for their execution context. This guarantees the coroutine will not be resumed before it has yielded.
  • Boost.Asio prevents a coroutine from staying indefinitely suspended if it detects that there are no handlers available to resume it. When this occurs, Boost.Asio will destroy the coroutine, causing the suspended stack to unwind. See this answer for more details.

在上面的示例代码中, spawn(yield_context) 重载,新协程将具有与调用协程相同的执行上下文(即strand),从而防止并行执行.

In the example code above, the spawn(io_service&) overload causes the resulting coroutine to have its own strand. As a result, if multiple threads are running the io_service, each of the coroutines may run in parallel, but are not guaranteed to do so. On the other hand, if one uses the spawn(yield_context) overload, the new coroutine will have the same execution context (i.e strand) as the calling coroutine, preventing parallel execution.

这篇关于直接在asio堆栈式协程中使用spawn安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆