协程局部变量在boost

Coroutine-local variable in boost

本文关键字:boost 局部变量      更新时间:2023-10-16

我正在寻找类似于线程局部变量的东西,但对于boost:: cor棕(实际上我使用boost:asio::spawn)。考虑以下代码:

void coroutine_work(boost::asio::yield_context yield) {
    async_foo( yield );
    some_function();
}
void some_function() {
    fprintf(log_fd, "%s Some function called", the_magic_request_id);
}

我想把这个the_magic_request_id设置为初始化请求时的某个值,它将像"当前请求id"一样服务。

如果没有这个,我必须将the_magic_request_id传递给每个功能和每个模块,这些功能和模块在项目中进行登录。some_function只是一个例子,实际上我有很多类,他们做不同的工作,但他们都需要yield_contextthe_magic_request_id来创建一个实例。我想简化这些类的接口。

可能是有可能设置"on_sleep"answers"on_resume"挂钩,这将设置一个全局变量?或者boost::coroutine已经为此提供了一些面向用户的机制?

不使用boost。协程(boost::asio::yield_context)你可以使用boost。光纤(user-land threads,boost::fibers::asio::yield_context)。提振。光纤支持fiber_specific_ptr (equals . to boost)。线程的thread_specific_ptr)。

文档:http://olk.github.io/libs/fiber/doc/html/index.html

可以使用绑定函数对象来包含状态。

事实上,绑定函数对象可以优雅地表示为带有捕获的lambda。确保捕获是按值的(这样你就不会意外地与其他实例共享状态),如果不是,它们所引用的对象就足够长寿。

extern std::ostream& log_stream; // for exposition only
struct coroutine_work {
    boost::uuids::uuid the_magic_request_id = boost::uuids::random_generator{}();
    void operator()(boost::asio::yield_context yield) {
        async_foo(yield);
        some_function();
    }
    void some_function() const {
        log_stream << the_magic_request_id << " Some function calledn";
    }
}

另外:

static void some_function(boost::uuids::uuid const& reqid) const {
    log_stream << reqid << " Some function calledn";
}
struct coroutine_work {
    boost::uuids::uuid the_magic_request_id = boost::uuids::random_generator{}();
    void operator()(boost::asio::yield_context yield) {
        async_foo(yield);
        some_function(the_magic_request_id);
    }
}

或者转换成lambda形式:

static void some_function(boost::uuids::uuid const& reqid) const {
    log_stream << reqid << " Some function calledn";
}
// somewhere else: 
{
    boost::uuids::uuid the_magic_request_id = boost::uuids::random_generator{}();
    auto coroutine_work = [the_magic_request_id](boost::asio::yield_context yield) {
        async_foo(yield);
        some_function(the_magic_request_id);
    }
}