What's the Deal with Boost.Asio and File I/O

What's the deal with boost.asio and file i/o?

Has boost.asio any kind of file support?

Starting with (I think) Boost 1.36 (which contains Asio 1.2.0) you can use [boost::asio::]windows::stream_handle or windows::random_access_handle to wrap a HANDLE and perform asynchronous read and write methods on it that use the OVERLAPPED structure internally.

User Lazin also mentions boost::asio::windows::random_access_handle that can be used for async operations (e.g. named pipes, but also files).

Is boost.asio file support mature enough for everyday file i/o?

As Boost.Asio in itself is widely used by now, and the implementation uses overlapped IO internally, I would say yes.

Will file support ever be added? Whats the outlook for this?

As there's no roadmap found on the Asio website, I would say that there will be no new additions to Boost.Asio for this feature. Although there's always the chance of contributors adding code and classes to Boost.Asio. Maybe you can even contribute the missing parts yourself! :-)

Boost asio for writing to files

I think what you want to do is perfectly fine, assuming that your IO-operation is sufficently complicated, in order to justfy the overhead of the async implementaion. My simple suggestion would look like this (copied from an old question):

#include <thread>
#include <functional>
#include <boost/asio.hpp>
#include <boost/bind.hpp>

void io_operation(int parameter) {
//Your stuff
}

int main ( int argc, char* argv[] ) {
boost::asio::io_service io_service;
boost::asio::io_service::work work(io_service);

//Set up a thread pool taking asynchronically care of your orders
std::vector<std::thread> threadPool;

for(size_t t = 0; t < std::thread::hardware_concurrency(); t++){
threadPool.push_back(std::thread(boost::bind(&boost::asio::io_service::run, &io_service)));
}

//Post an IO-operation
io_service.post(std::bind(io_operation, 123));

//Join all threads at the end
io_service.stop();
for(std::thread& t : threadPool) {
t.join();
}
}

This assumes, that you can use C++11 threads. Also you should be aware, that this does not ensure only one thread is writing to a specific file. Therefore you may need to use strands to ensure that calls for a specific file are not handeled in
parallel.

Scalability of Boost.Asio

We are using 1.39 on several Linux flavors for timers, network (both TCP and UDP), serial (20+ lines, two of which run at 500 kbps), and inotify events, and while we don't have many socket connections, we do have a few hundred async timers at any time. They are in production and they work well, for us. If I were you, I'd make up a quick prototype and performance-test it.

Boost 1.43 claims a number of Linux-specific performance improvements in ASIO, but I am yet to benchmark them for our product.

boost::asio extension TCP socket

The short answer to my question is using epoll. According to wikipedia, epoll is a scalable I/O event notification mechanism for Linux, first introduced in Linux kernel 2.5.44.

select(2) can monitor up to FD_SETSIZE number of descriptors at a time, typically a small number determined at libc's compile time. Instead, epoll has no such fixed limits, and does not perform any linear scans. Hence it is able to perform better and handle a larger number of events.

For a tutorial on how to use epoll go at banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c/

As for Boost, on many platforms, Boost.Asio implements the Proactor design pattern in terms of a Reactor, such as select(kernel 2.4), epoll(kernel 2.6) or kqueue(Mac OS).

On Windows NT, 2000 and XP, Boost.Asio takes advantage of overlapped I/O to provide an efficient implementation of the Proactor design pattern.

More on Boost:

www.boost.org/doc/libs/1_52_0/doc/html/boost_asio/overview/core/async.html

www.boost.org/doc/libs/1_35_0/doc/html/boost_asio/design/implementation.html

How to perform Cross-Platform Asynchronous File I/O in C++

boost has an asio library, which I've not used before (it's not on NASA's list of approved third-party libraries).

My own approach has been to write the file reading code twice, once for Windows, once for the POSIX aio API, and then just pick the right one to link with.

For Windows, use OVERLAPPED (you have to enable it in the CreateFile call, then pass an OVERLAPPED structure when you read). You can either have it set an event on completion (ReadFile) or call a completion callback (ReadFileEx). You'll probably need to change your main event loop to use MsgWaitForMultipleObjectsEx so you can either wait for the I/O events or allow callbacks to run, in addition to receiving WM_ window messages. MSDN has documentation for these functions.

For Linux, there's either fadvise and epoll, which will use the readahead cache, or aio_read which will allow actual async read requests. You'll get a signal when the request completes, which you should use to post an XWindows message and wake up your event processing loop.

Both are a little different in the details, but the net effect is the same -- you request a read which completes in the background, then your event dispatch loop gets woken up when the I/O finishes.

boost::asio error The I/O operation has been aborted...

Your tcp_connection object or your buffer object is likely going out of scope prior to the async operation completing.

Since your program is based on one of the tutorial examples, why don't you check out another of the examples that reads some data as well: http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/example/echo/async_tcp_echo_server.cpp

The reason your class goes out of scope is that you are no longer using shared_from_this(). What this does is create a shared_ptr to your class that is stored by the bind handler. This means that the shared_ptr will keep your class alive until your handler is called.

This is also why you need to inherit from enable_shared_from_this.

The last shared_ptr that goes out of scope will delete your class instance.

File socket I/O using UDP with Boost ASIO

You're looking for local::datagram_protocol::endpoint and local::datagram_protocol::socket.



Related Topics



Leave a reply



Submit