gpt4 book ai didi

c++ - 如何等待 asio 处理程序?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:31:25 24 4
gpt4 key购买 nike

我有一个围绕 boost::asio::io_service 运行的对象,它具有一些属性。类似的东西:

class Foo
{
private:

// Not an int in my real code, but it doesn't really matter.
int m_bar;
boost::asio::io_service& m_io_service;
boost::asio::strand m_bar_strand;
};

m_bar 只能从通过链 m_bar_strand 调用的处理程序中使用。这使我不会从这些处理程序中锁定。

为了从运行 io_service::run() 的线程外部设置 m_bar 属性,我编写了一个 asynchronous_setter,如下所示:

class Foo
{
public:
void async_get_bar(function<void (int)> handler)
{
m_bar_strand.post(bind(&Foo::do_get_bar, this, handler));
}

void async_set_bar(int value, function<void ()> handler)
{
m_bar_strand.post(bind(&Foo::do_set_bar, this, value, handler));
}

private:

void do_get_bar(function<void (int)> handler)
{
// This is only called from within the m_bar_strand, so we are safe.

// Run the handler to notify the caller.
handler(m_bar);
}

void do_set_bar(int value, function<void ()> handler)
{
// This is only called from within the m_bar_strand, so we are safe.
m_bar = value;

// Run the handler to notify the caller.
handler();
}

int m_bar;
boost::asio::io_service& m_io_service;
boost::asio::strand m_bar_strand;
};

这非常有效,但现在我想编写一个 set_bar 的同步版本,它设置值并仅在设置有效时返回。它仍然必须保证有效集将出现在 m_bar_strand 中。理想情况下,可以重入。

我可以想象带有信号量的解决方案可以从处理程序中进行修改,但我提出的所有内容似乎都很老套而且真的不优雅。 Boost/Boost Asio 中有什么允许这样的事情吗?

您将如何着手实现此方法?

最佳答案

如果你需要同步等待一个值被设置,那么Boost.Thread的futures可能会提供一个优雅的解决方案:

The futures library provides a means of handling synchronous future values, whether those values are generated by another thread, or on a single thread in response to external stimuli, or on-demand.

简而言之,一个boost::promise创建并允许在其上设置值。稍后可以通过关联的 boost::future 检索该值.这是一个基本示例:

boost::promise<int> promise;
boost::unique_future<int> future = promise.get_future();

// start asynchronous operation that will invoke future.set_value(42)
...

assert(future.get() == 42); // blocks until future has been set.

这种方法还有两个显着的好处:

  • future 是 C++11 的一部分。
  • 异常甚至可以通过promise::set_exception() 传递给future ,支持以优雅的方式向调用者提供异常或错误。

这是一个基于原始代码的完整示例:

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>

class Foo
{
public:

Foo(boost::asio::io_service& io_service)
: m_io_service(io_service),
m_bar_strand(io_service)
{}

public:

void async_get_bar(boost::function<void(int)> handler)
{
m_bar_strand.post(bind(&Foo::do_get_bar, this, handler));
}

void async_set_bar(int value, boost::function<void()> handler)
{
m_bar_strand.post(bind(&Foo::do_set_bar, this, value, handler));
}

int bar()
{
typedef boost::promise<int> promise_type;
promise_type promise;

// Pass the handler to async operation that will set the promise.
void (promise_type::*setter)(const int&) = &promise_type::set_value;
async_get_bar(boost::bind(setter, &promise, _1));

// Synchronously wait for promise to be fulfilled.
return promise.get_future().get();
}

void bar(int value)
{
typedef boost::promise<void> promise_type;
promise_type promise;

// Pass the handler to async operation that will set the promise.
async_set_bar(value, boost::bind(&promise_type::set_value, &promise));

// Synchronously wait for the future to finish.
promise.get_future().wait();
}

private:

void do_get_bar(boost::function<void(int)> handler)
{
// This is only called from within the m_bar_strand, so we are safe.

// Run the handler to notify the caller.
handler(m_bar);
}

void do_set_bar(int value, boost::function<void()> handler)
{
// This is only called from within the m_bar_strand, so we are safe.
m_bar = value;

// Run the handler to notify the caller.
handler();
}

int m_bar;
boost::asio::io_service& m_io_service;
boost::asio::strand m_bar_strand;
};

int main()
{
boost::asio::io_service io_service;
boost::asio::io_service::work work(io_service);
boost::thread t(
boost::bind(&boost::asio::io_service::run, boost::ref(io_service)));

Foo foo(io_service);
foo.bar(21);
std::cout << "foo.bar is " << foo.bar() << std::endl;
foo.bar(2 * foo.bar());
std::cout << "foo.bar is " << foo.bar() << std::endl;

io_service.stop();
t.join();
}

它提供以下输出:

foo.bar is 21
foo.bar is 42

关于c++ - 如何等待 asio 处理程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20709725/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com