文件描述符异步等待使用Boost短耳 [英] Async wait on file descriptor using Boost Asio

查看:125
本文介绍了文件描述符异步等待使用Boost短耳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想的D-Bus集成与我的的boost :: ASIO 应用程序。

的D-Bus有枚举一组Unix文件描述(主要是插座,但也可能是FIFO的),被关注的API。
当这些描述符有东西要读我应该告知的D-Bus API,因此它能够读取他们做的事情。

目前我在做这样的:

 使用boost ::支持ASIO :: POSIX :: stream_descriptor;
无效read_handle(stream_descriptor *递减,常量的boost ::系统::错误_ code和; EC,
                 的std ::为size_t bytes_read缓存)
{
    如果(!EC){
        stream_descriptor :: bytes_readable命令(真);
        descriptor-> io_control(命令);
        的std ::为size_t bytes_readable = command.get();
        性病::法院LT&;< 它认为我应该读<< bytes_readable
            << 字节<<的std :: ENDL;
    }其他{
        性病::法院LT&;< 有错误<<的std :: ENDL;
    }
}无效watch_descriptor(提高:: ASIO :: io_service对象和放大器; IOS,INT类file_descriptor)
{
    //创建描述符的ASIO重新presentation
    stream_descriptor * DESC =新stream_descriptor(IOS);
    desc->分配(类file_descriptor);    //尝试读取0字节只是被告知,有一些要读
    的std ::矢量<&烧焦GT;缓冲液(0);
    desc-> async_read_some(升压:: ASIO ::缓​​冲液(缓冲液,0),
        提高::绑定(read_handle,递减,_1,_2));
}

但处理程序被调用马上说,它有0字节被读取。我想,只有当有东西要读它被调用,而提高:: ASIO的无法阅读。它应该采取行动,就像一个荣耀的选择()。有一个简单的方法来做到这一点?

PS:我大量使用了的boost :: ASIO 在我的软件,这是它只是一小部分,所以我想不依靠巧舌如簧或其他mainloops。


解决方案

这是precisely问题<一href=\"http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/reference/null_buffers.html\">null_buffers WAS <一个href=\"http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/overview/core/reactor.html\">designed为


  

有时一个程序必须被整合
  与想要一个第三方库
  执行I / O操作本身。
  为了推动这项工作,Boost.Asio的
  包括null_buffers类型,可以
  可以与用于读取和写入
  操作。一个null_buffers操作
  不返回,直到I / O对象
  准备来执行该操作。


  
  

作为一个例子,为了执行
  非阻塞读的东西像
  可使用以下:


  IP :: TCP ::插座插座(my_io_service);
...
IP :: TCP ::插座:: non_blocking NB(真);
socket.io_control(NB);
...
socket.async_read_some(null_buffers(),read_handler);
...
无效read_handler(的boost ::系统::错误_ code EC)
{
  如果(!EC)
  {
    的std ::矢量&lt;&烧焦GT; BUF(socket.available());
    socket.read_some(缓冲器(BUF));
  }
}

另外还有一个<一个href=\"http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/example/nonblocking/third_party_lib.cpp\">excellent例如的包含的文件中。

I'm trying to integrate D-Bus with my boost::asio application.

D-Bus has an API that enumerates a set of Unix file descriptors (mainly sockets but could also be FIFOs) to be watched. When those descriptors have something to be read I should inform the D-Bus API so it can read them and do it's thing.

Currently I'm doing this:

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));
}

But the handler is called right away saying that it has 0 bytes to be read. I would like it to be called only when there is something to be read, but boost::asio CAN NOT read it. It should act just as a glorified select(). Is there a simple way to do that?

PS: I'm extensively using boost::asio in my software, this is just a small part of it, so I would like not to depend on glib or other mainloops.

解决方案

This is precisely the problem null_buffers was designed for.

Sometimes a program must be integrated with a third-party library that wants to perform the I/O operations itself. To facilitate this, Boost.Asio includes a null_buffers type that can be used with both read and write operations. A null_buffers operation doesn't return until the I/O object is "ready" to perform the operation.

As an example, to perform a non-blocking read something like the following may be used:

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));
  }
}

There's also an excellent example included in the documentation.

这篇关于文件描述符异步等待使用Boost短耳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆