I have adapted step 3 of the Boost asio tutorial to run forever, and display "tick" and "tock" once per second instead of the counter:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
void print(const boost::system::error_code& /*e*/,
boost::asio::deadline_timer* t, int* count)
{
if( !((*count) % 2) )
std::cout << "tick\n";
else
std::cout << "tock\n";
++(*count);
t->expires_at(t->expires_at() + boost::posix_time::seconds(1));
t->async_wait(boost::bind(print,
boost::asio::placeholders::error, t, count));
}
int main()
{
boost::asio::io_service io;
int count = 0;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(1));
t.async_wait(boost::bind(print,
boost::asio::placeholders::error, &t, &count));
io.run();
std::cout << "Final count is " << count << "\n";
return 0;
}
Now I want to asynchronously be able to handle a keypress on stdin. Is there an io_service handler I can use to respond to keypresses, without blocking sleeps or waits?
For example, I'd like to be able to implement a handler function similar to:
void handle_keypress(const boost::error_code&,
char c)
{
std::cout << "Tap '" << c << "'\n";
}
And I would expect my invocation of this handler to be something along the lines of:
char c = 0;
boost::asio::stdin_receiver sr(io);
st.async_wait(boost::bind(handle_keypress, boost::asio::placeholders::error, &c));
io.run();
Is this something I can do with asio, either by using a builtin service handler, or writing my own?
EDIT, ELABORATION:
I have seen this question, but the linked-to code in the accpeted answer simply does this in main
:
while (std::cin.getline(
The application I'm writing isn't this simple tick-tock-tap gizmo I've outlined above, but will be a multicast server. Several worker threads will be sending packets to multicast groups, responding to messages from the main thread, and sending messages back to the main thread. The application, in turn, will be "driven" by input from the stdin -- for example, when the user presses the "P" key, multicast broadcast will be paused, and when the hit "Q" the whole thing will shut down. In the main thread, all I'll do in response to these inputs is send messages to the worker threads.
The while
loop above won't work in my scenario because while it's waiting for stdin input from the user, the main thread will not be able to process messages coming in from the worker threads. Some of those messages from the worker thread will generate output to stdout.
run
is called in a different thread, but in the non-POSIX example thecin.getline
is in the main thread. I want a solution that works in both Windows and Linux, I should have mentioned, and the POSIX version of the chat client is#ifdef
-ed away. – Stomach