检查输入和睡眠提升线程

时间:2014-02-18 00:24:37

标签: c++ linux boost blocking cin

我正在尝试构建一个检查用户输入的线程,如果输入等于“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";
}

我的意图如何完成?

1 个答案:

答案 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()来轻松添加线程。