1

我正在寻找类似于线程局部变量的东西,但对于 boost::corotine (实际上我使用 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_context并且the_magic_request_id为了创建一个实例。我想简化这些类的接口。

可能可以设置“on_sleep”和“on_resume”钩子,这将设置一个全局变量?或者 boost::coroutine 已经为此提供了一些现成的用户机制?没有在文档中找到可用的东西。

4

2 回答 2

3

除了使用 boost.coroutine (boost::asio::yield_context),你可以使用 boost.fiber (user-land threads,boost::fibers::asio::yield_context)。boost.fiber 支持 Fiber_specific_ptr(相当于 boost.thread 的 thread_specific_ptr)。

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

于 2015-09-04T06:14:36.917 回答
0

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

事实上,绑定函数对象可以优雅地表示为带有捕获的 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 called\n";
    }
}

或者:

static void some_function(boost::uuids::uuid const& reqid) const {
    log_stream << reqid << " Some function called\n";
}

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 called\n";
}

// 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);
    }
}
于 2015-09-03T16:28:39.897 回答