Reputation: 1288
I am using asio for tcp server and I plan to use C++11 std for thread as well. My final goal is to have this application on Linux but I am testing it on Windows first using Visual Studio 2015.
First I am using blocking so I found there were discussion on how to stop a thread waiting on accept. There were pre-C++11 solutions such as pipe, and select. I am looking for the asio way.
asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 13));
backAcceptor = &acceptor;
tcp::socket socket(io_service);
asio::error_code ec;
acceptor.accept(socket, &ec);
Second way is to use asynchronous, but I prefer to use the asio header only. The compile complained that the asio::placeholder doesn't have this member but according to the comment, the solution is applied:
asio::async_write(socket_, asio::buffer(message_),
std::bind(&tcp_connection::handle_write, shared_from_this(),
std::placeholders::_1,
std::placeholders::_2
));
run() still block there. And I am looking for method to resume this thread from main.
asio::io_service io_service;
tcp_server server(io_service);
io_service.run();
The third way is, to set a timeout here. But it doesn't stop my accept. Plus, the answer was in 2012. I hope there is new was to solve this by now.
To test the scenarios, I first have a thread to either blocks at synchronous accept() or at asynchronous run(). When the thread is running, the main then waits for 2 seconds, and tries to stop the thread. Then I wait for the thread to complete using join.
For the first method "Synchronous", I tried to use acceptor.cancel() and the thread arrived at the join. Is this the correct way?
Second method "Async", although I am still not clear how to stop this thread officially, I succeeded using io_service.stop() to actually cancel it.
Please let me know whether my solutions is correct and I will continue to try different solutions.
Upvotes: 1
Views: 951
Reputation: 393064
I happen to have played around with a non-typical approach with run_one
and no threading, that specifically allows you timeout individual "non-asynch" operations:
In fact, you do post the asynch operations, but then you call await_operation
with a timeout:
async_connect(socket, ip::tcp::resolver(ioservice).resolve({address, port}), raise());
await_socket(std::chrono::seconds(6));
This is the equivalent of doing a synchronous connect
but with the possibility to timeout. No threads, blocking run()
or other puppies were harmed.
See the linked answer for demos
PS. Use deadline_timer
with posix_time
if you don't want the high_resolution_timer
which works nicely with std::chrono
Upvotes: 1