文件描述符异步等待使用Boost短耳 [英] Async wait on file descriptor using Boost Asio
问题描述
我想的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 onglib
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屋!