I have a server and a client code written in boost ASIO and it works pretty fine. Since synchronous and asynchornous boost asio API's are different, is it possible in any way that the code I have written for asynchronous communication behaves and works in a synchronous fashion instead of asynchronous. ?
0
votes
What do you mean? What code do you have, and exactly what parts do you want to run synchronously. What does it mean for it to run synchronously?
- sehe
So, @sehe , what I mean is that I have a code written using async_accept, async_read and async_write. What asynchronous API's do is that when the I/O operation is complete, they call a function which does post processing. Whereas, with synchronous I/O, unless the current i/o is complete, it cannnot go to the next operation. So, what I was asking i that can the code written using async API's be used to do synchronous i/o ?
- Nishant Sharma
My answer shows it
- sehe
@NishantSharma Please remember to accept an answer to your question[s].
- Blacktempel
1 Answers
2
votes
You can run any asynchronous code on a dedicated io_service, and simply run the service blocking:
#include <boost/asio.hpp>
#include <boost/asio/high_resolution_timer.hpp>
#include <iostream>
using namespace std::chrono_literals;
using namespace boost::asio;
using boost::system::system_error;
io_service svc;
high_resolution_timer deadline(svc, 3s);
void task_foo() {
deadline.async_wait([](system_error) { std::cout << "task done\n"; });
}
int main() {
task_foo();
std::cout << "Before doing work\n";
svc.run(); // blocks!
std::cout << "After doing work\n";
}
Prints
Before doing work
task done
After doing work
Alternatively:
You can always use futures that you can then await blocking:
#include <boost/asio.hpp>
#include <boost/asio/high_resolution_timer.hpp>
#include <boost/make_shared.hpp>
#include <future>
#include <iostream>
#include <thread>
using namespace std::chrono_literals;
using namespace boost::asio;
using boost::system::system_error;
io_service svc;
high_resolution_timer deadline(svc, 3s);
std::future<int> task_foo() {
auto p = boost::make_shared<std::promise<int> >();
auto fut = p->get_future();
deadline.async_wait([p](system_error) {
std::cout << "task done\n";
p->set_value(42);
});
return fut;
}
int main() {
auto foo = task_foo();
std::cout << "Before doing work\n";
std::thread([] { svc.run(); }).detach(); // doesn't block!
std::cout << "After starting work\n"; // happens before task completion
auto result = foo.get(); // blocks again!
std::cout << "Task result: " << result << "\n";
}
Prints
Before doing work
After starting work
task done
Task result: 42
This way you can still have the io_service running concurrently and don't require it to complete even though a particular task completes synchronously (foo.get())