我正在尝试构建一个检查用户输入的线程,如果输入等于“exit”,它会关闭所有其他线程。
我使用cin
的方式似乎停止了线程。线程应该运行,检查用户输入,如果有,它等于“退出”,关闭runProcesses
。
这是我的代码无法正常工作,因为“newline stopped”永远不打印,“running”只打印一次:
void check_for_cin() {
while ( runProcesses ) {
cout << "running";
string input;
std::getline( std::cin, input );
//while ( std::getline( std::cin, input ) ) {
if ( !input.empty() ) {
if ( input == "exit" ) {
runProcesses = false;
cout << "exiting" << ", run processes: " << runProcesses;
}
}
cout << "newline stopped";
boost::this_thread::sleep( boost::posix_time::seconds( 1 ) );
}
cout << "no longer checking for input";
}
我的意图如何完成?
答案 0 :(得分:2)
查看Asio的文件描述符服务对象。
Posix的'reactor'风格不同步,所以你实际上并不需要线程来实现异步性。
我的示例显示了在输出'exit'时退出的读取循环/或/当超时到期时(10s)。
#include <boost/asio.hpp>
#include <boost/asio/posix/stream_descriptor.hpp>
boost::asio::io_service my_io_service;
boost::asio::posix::stream_descriptor in(my_io_service, ::dup(STDIN_FILENO));
boost::asio::deadline_timer timer(my_io_service);
// handle timeout
void timeout_expired(boost::system::error_code ec) {
if (!ec)
std::cerr << "Timeout expired\n";
else if (ec == boost::asio::error::operation_aborted) // this error is reported on timer.cancel()
std::cerr << "Leaving early :)\n";
else
std::cerr << "Exiting for another reason: " << ec.message() << "\n";
// stop the reading loop
in.cancel();
in.close();
}
// set timeout timer
void arm_timeout()
{
timer.expires_from_now(boost::posix_time::seconds(10));
timer.async_wait(timeout_expired);
}
// perform reading loop
void reading_loop()
{
std::cerr << "(continueing input...)\n";
static boost::asio::streambuf buffer; // todo some encapsulation :)
async_read_until(in, buffer, '\n', [&](boost::system::error_code ec, size_t bytes_transferred) {
if (!ec)
{
std::string line;
std::istream is(&buffer);
if (std::getline(is, line) && line == "exit")
ec = boost::asio::error::operation_aborted;
else
reading_loop(); // continue
}
if (ec)
{
std::cerr << "Exiting due to: " << ec.message() << "\n";
// in this case, we don't want to wait until the timeout expires
timer.cancel();
}
});
}
int main() {
arm_timeout();
reading_loop();
my_io_service.run();
}
在Windows上,您可以使用等效的Windows Stream Handle
您可以通过在多个线程上运行my_io_service.run()
来轻松添加线程。