Thread: [asio-users] Questions about file io when using boost.asio
Brought to you by:
chris_kohlhoff
From: lampahome <pah...@mi...> - 2020-09-01 08:35:46
|
Hi, all I'm a rookie to boost.asio. I write a program to write files asynchronously by boost.asio. But I'm confused with some point. 1. I need to add job to boost::asio::io_service and call io_service.run(), then it will start running all jobs. Is there any function automatically running newly jobs after I add job? 2. If io_service.run() failed, is there any queue to let me know which job failed? Or it only jump exception? thanks |
From: Jeff A. <je...@p2...> - 2020-09-01 09:26:43
|
On 01/09/2020 09:43, lampahome wrote: > Hi, all > I'm a rookie to boost.asio. > > I write a program to write files asynchronously by boost.asio. But I'm > confused with some point. You're not alone. Even with the docs, the learning curve is steep at first. > 1. I need to add job to boost::asio::io_service and call > io_service.run(), then it will start running all jobs. Is there any > function automatically running newly jobs after I add job? It's hard to answer without knowing what you want to do. The service needs to believe it has a reason to live (jobs queued), otherwise it will quit. For example, you can use functions like io_service.post() to ask a different service to do something (e.g., you have two threads and one wants the other to do something). Or if you have only one thread (main), you can push some task that never finishes until its good and ready and then let your whole program happen in that loop. As long as it's event-based, it will work out. Is your program event-based or is it just that you have one file operation that needs to be async? > 2. If io_service.run() failed, is there any queue to let me know which > job failed? Or it only jump exception? What do you mean by failed? The io_service probably didn't fail, it's some task you asked it to do that failed. In that case, you probably meant to catch the failure yourself. I.e., instead of your task being DoWork() maybe you meant to write try { DoWork } catch(const std::exception& e) { std::err << "Well, that didn't go very well." << std::end; } -- Jeff Abrahamson +33 6 24 40 01 57 +44 7920 594 255 http://p27.eu/jeff/ http://transport-nantes.com/ |
From: lampahome <pah...@mi...> - 2020-09-01 09:46:36
|
> > > program event-based or is it just that you have one file operation that > needs to be async? > My program is event-based 2. If io_service.run() failed, is there any queue to let me know which job > failed? Or it only jump exception? > > What do you mean by failed? The io_service probably didn't fail, it's > some task you asked it to do that failed. In that case, you probably meant > to catch the failure yourself. I.e., instead of your task being > My mistake. I mean the io operation failed. It seems read/write handler can handle failed situations, but is there a centralized queue(? or something) can collect these failed or all operations? I want to do is like libaio in unix system and want to find some library to reach that easier. I have two threads(or one is main thread) and one thread will submit io of file as more as it can, and another one thread will check the execution state(i.e. return code) of each io. I thought this design pattern will improve my program. Looks like the io_context, async_read, and async_write will help me, but the handler in Doc seems naive? void handle_write_error(const boost::system::error_code& ec, std::size_t){...} Every document told above handler, but it seems can only two arguments? Maybe some misunderstand, thank u. |
From: Jeff A. <je...@p2...> - 2020-09-01 09:58:03
|
On 01/09/2020 11:46, lampahome wrote: > >> 2. If io_service.run() failed, is there any queue to let me know >> which job failed? Or it only jump exception? > > What do you mean by failed? The io_service probably didn't fail, > it's some task you asked it to do that failed. In that case, you > probably meant to catch the failure yourself. I.e., instead of > your task being > > My mistake. I mean the io operation failed. It seems read/write > handler can handle failed situations, but is there a centralized > queue(? or something) can collect these failed or all operations? The way I do this is that I call the dispatch functions with closures, so the function executing has the state it needs to do whatever it's going to do. And when I call a function with a completion handler, I again provide a closure so that it can do what it needs to do. One of the things a completion handler can do is check the result code of the operation. Now, I'll only class myself as "somewhere between newbie and expert but at neither extreme", so it's possible this conversation will uncover some problem with my error handling. > I want to do is like libaio in unix system and want to find some > library to reach that easier. Hmm, I'm on linux and yet I find libasio works quite well for me. Maybe I missed something. Although libasio gives me a bit more support, I think, than just libaio's completion handlers. > I have two threads(or one is main thread) and one thread will submit > io of file as more as it can, and another one thread will check the > execution state(i.e. return code) of each io. I thought this design > pattern will improve my program. I'd use completion handlers for checking return codes. Here's a snippet from a function of mine, in case it can help: void TcpConnection::SendMessage(...) { boost::asio::async_write( *sockets_[connection_index], boost::asio::buffer(send_queue_[connection_index].front()), [this, connection_index](boost::system::error_code ec, size_t length) { LOGGABLE; // This is the completion handler. if (ec) { LOG_WARNING << "Failed to send message: " << AsioError(ec); SendFailure(connection_index, ec); return; } // ... -- Jeff Abrahamson +33 6 24 40 01 57 +44 7920 594 255 http://p27.eu/jeff/ http://transport-nantes.com/ |
From: lampahome <pah...@mi...> - 2020-09-01 10:30:30
|
> > > I want to do is like libaio in unix system and want to find some library > to reach that easier. > > Hmm, I'm on linux and yet I find libasio works quite well for me. Maybe I > missed something. Although libasio gives me a bit more support, I think, > than just libaio's completion handlers. > I will try libasio and thanks your help > I have two threads(or one is main thread) and one thread will submit io of > file as more as it can, and another one thread will check the execution > state(i.e. return code) of each io. I thought this design pattern will > improve my program. > > I'd use completion handlers for checking return codes. Here's a snippet > from a function of mine, in case it can help: > > void TcpConnection::SendMessage(...) { > > boost::asio::async_write( > *sockets_[connection_index], > boost::asio::buffer(send_queue_[connection_index].front()), > [this, connection_index](boost::system::error_code ec, size_t > length) { > LOGGABLE; > // This is the completion handler. > if (ec) { > LOG_WARNING << "Failed to send message: " << AsioError(ec); > SendFailure(connection_index, ec); > return; > } > // ... > > > I forgot which handler can use lambda function. Thank you again. I will continue combine your advise and look up Doc to develope. |