使用Boost Asio异步等待文件描述符

时间:2011-01-13 22:36:40

标签: c++ boost boost-asio dbus

我正在尝试将D-Bus与我的boost::asio应用程序集成。

D-Bus有一个API,可以枚举一组要监视的Unix文件描述符(主要是套接字,但也可以是FIFO)。 当那些描述符有东西需要阅读时,我应该通知D-Bus API,这样它就可以读取它们并做它的事情。

目前我正在这样做:

using boost::asio::posix::stream_descriptor;
void read_handle(stream_descriptor* desc, const boost::system::error_code& ec,
                 std::size_t bytes_read)
{
    if (!ec) {
        stream_descriptor::bytes_readable command(true);
        descriptor->io_control(command);
        std::size_t bytes_readable = command.get();
        std::cout << "It thinks I should read" << bytes_readable
            << " bytes" << std::endl;
    } else {
        std::cout << "There was an error" << std::endl;
    }
}

void watch_descriptor(boost::asio::io_service& ios, int file_descriptor)
{
    // Create the asio representation of the descriptor
    stream_descriptor* desc = new stream_descriptor(ios);
    desc->assign(file_descriptor);

    // Try to read 0 bytes just to be informed that there is something to be read
    std::vector<char> buffer(0);
    desc->async_read_some(boost::asio::buffer(buffer, 0),
        boost::bind(read_handle, desc, _1, _2));
}

但是立即调用处理程序说它有0个字节需要读取。我希望只有在有东西需要阅读时才能调用它,但是boost :: asio 不能读取它。它应该像一个美化的select()一样行事。有没有一种简单的方法可以做到这一点?

PS:我在我的软件中广泛使用boost::asio,这只是其中的一小部分,所以我不想依赖glib或其他主循环。

1 个答案:

答案 0 :(得分:28)

这正是问题null_buffersdesigned

  

有时必须整合一个程序   与想要的第三方库   自己执行I / O操作。   为此,Boost.Asio   包括可以的null_buffers类型   与读和写一起使用   操作。 null_buffers操作   在I / O对象出现之前不会返回   “准备好”执行操作。

     

作为一个例子,执行一个   非阻塞读取类似的东西   可能会使用以下内容:

ip::tcp::socket socket(my_io_service);
...
ip::tcp::socket::non_blocking nb(true);
socket.io_control(nb);
...
socket.async_read_some(null_buffers(), read_handler);
...
void read_handler(boost::system::error_code ec)
{
  if (!ec)
  {
    std::vector<char> buf(socket.available());
    socket.read_some(buffer(buf));
  }
}

文档中还包含excellent example