【问题标题】:Boost asio non-blocking IO without callbacks无需回调即可提升 asio 非阻塞 IO
【发布时间】:2016-02-02 10:30:01
【问题描述】:

是否可以在不使用异步回调的情况下使用 Boost 的 asio 进行非阻塞 IO 即相当于O_NONBLOCK 套接字选项。

我基本上想要这个功能:

template<typename SyncWriteStream,
         typename ConstBufferSequence>
std::size_t write_nonblock(
    SyncWriteStream & s,
    const ConstBufferSequence & buffers);

此函数将写入尽可能多的字节并立即返回。它可能会写入 0 个字节。

有可能吗?

【问题讨论】:

  • 如果立即返回,它如何“返回”写入的字节数?您如何判断数据是否已发送?如果有错误?没有某种回调是不可能的。
  • 它会将它们写入内部缓冲区。看看O_NONBLOCK
  • 我知道非阻塞套接字,我想知道如果您不想使用回调,您将如何告诉程序write 调用成功或失败。你怎么会知道 write 函数何时在没有某种轮询的情况下完成?你会在主程序中这样做吗?轮询一些状态缓冲区?异步编程不仅仅是“调用非阻塞函数,然后继续我的快乐方式”那么简单。
  • 以后的调用会失败。很简单。

标签: c++ boost boost-asio nonblocking


【解决方案1】:

是的,使用non_blocking()方法将socket置于Asio非阻塞模式:

template<typename SyncWriteStream,
         typename ConstBufferSequence>
std::size_t write_nonblock(
    SyncWriteStream & s,
    const ConstBufferSequence & buffers)
{
    s.non_blocking(true);
    boost::system::error_code ec;
    auto bytes = s.send(buffers, 0, ec);
    if (bytes == 0 && !(ec == boost::asio::error::would_block))
        throw boost::system::system_error(ec, "write_nonblock send");
    return bytes;
}

【讨论】:

  • 我可以在阅读时做同样的事情吗?我是否必须在每个套接字读取或写入调用之前设置s.non_blocking(true)
  • @SegmentationFault 是的,您可以使用receive 成员函数执行单次读取。 non_blocking 属性在调用之间保持不变,因此您不必每次都重新发出 s.non_blocking(true)
【解决方案2】:

s.non_blocking(true) 的方式行不通。 如果你检查send 的实现,它使用socket_ops::sync_send,如果发送失败,它会使用poll_write

所以它仍然在顶层阻塞。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-18
    • 1970-01-01
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    • 2010-11-17
    • 2012-08-17
    • 1970-01-01
    相关资源
    最近更新 更多