【问题标题】:ASIO proper handling of multiple threads + strand + socket + timerASIO 正确处理多线程 + strand + socket + timer
【发布时间】:2020-09-23 14:29:02
【问题描述】:

我正在使用最新的 ASIO 版本(截至此时为 1.18.0)。目前正在设计一个带定时器的多线程异步 TCP 服务器(用于超时)。我有一个io_context,有多个线程调用它的run() 函数。我接受这样的新连接:

void Server::AcceptConnection()
{
    acceptor_.async_accept(asio::make_strand(io_context_),
            [this](const asio::error_code& error, asio::ip::tcp::socket peer) {
                if (!error) {
                    std::make_shared<Session>(std::move(peer))->run();
                }
                AcceptConnection();
            });
}

这里是Session 类的精简版:

class Session : public std::enable_shared_from_this<Session>
{
public:
    Session(asio::ip::tcp::socket&& peer) : peer_(std::move(peer)) {}
    void run()
    {
        /*
        asio::async_read(peer_, some_buffers_, some_callback_);
        timeout_timer_.expires_after();
        timeout_timer_.async_wait();
        // etc
        */
    }
    
private:
    asio::ip::tcp::socket peer_;
    asio::steady_timer timeout_timer_{peer_.get_executor()};
}

请注意定时器的初始化。 另外,请注意,我没有为套接字和计时器的异步处理程序使用任何类型的 strand::wrap()asio::bind_executor() 包装器,因为据我所知,如果我用正确的方法初始化对象,则不再需要它们执行者。

这里的问题是:这是在 TCP 连接使用的同一链中使用计时器处理链内 TCP 连接的正确方法吗?

注意:定时器用于在超时后中止 TCP 连接。

【问题讨论】:

  • 如果有什么问题值得一票,那就是这个问题。很难理解为什么示例中没有这种简单的技术,但如果有,我肯定找不到。

标签: c++ server boost-asio asio


【解决方案1】:

是的,这也是我使用新接口编写内容的方式。

我记得当我开始使用新界面时也有同样的顾虑,最终检查各种完成处理程序确实在预期的链上运行,他们确实这样做了。

总而言之,这些都大大简化了库的使用。

【讨论】:

  • 这确实消除了使用中的大量复杂性。奇怪的是它没有更好的记录,真的。
  • @AllanBazinet “更好”的文档的唯一方法是详细说明它是如何(不统一)以及它是如何成为变化的。这势必会产生更多的混乱。 IMO 文档的“设计/为什么”部分非常不被重视(例如here),当然还有changelog。我确实认为一些更好的“新闻提要”是非常受欢迎的。
猜你喜欢
  • 2020-10-03
  • 1970-01-01
  • 2017-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-01
  • 2021-11-22
相关资源
最近更新 更多