简体   繁体   中英

How can I terminate a C++11 thread while it's waiting for std::cin?

I'm working on a Console class for console IO (right now just input, though) and I'm polling input from std::cin in my loop by having a background thread constantly checking for input. However, while it reads input fine, I (expectedly) ran into an issue where after I close my main window (GLFW) the console window is still sitting in the background waiting to either be closed out or receive input. I'm looking for a way to terminate the thread, but couldn't find any information on a good way to do it for this scenario. Any ideas?

console.h

class Console
{
    public:
        Console();
        ~Console();

        bool isInputAvailable();
        std::string pullLastInput();

    private:
        bool do_quit;
        void thread_input();
        std::thread in_thread;
        std::queue<std::string> input_queue;
};

console.cpp:

Console::Console() : in_thread(&Console::thread_input, this)
{
    do_quit = false;
}

Console::~Console()
{
    do_quit = true;
    in_thread.join();
}

bool Console::isInputAvailable()
{
    return input_queue.size() > 0;
}

std::string Console::pullLastInput()
{
    std::string input;
    input = input_queue.front();
    input_queue.pop();

    return input;
}

void Console::thread_input()
{
    std::string input;
    while (!do_quit)
    {
        std::cin >> input;

        input_queue.push(input);
    }
}

In your main window, when quitting, either by using the onClose event or in the destructor function, call std::terminate or the destructor of the background thread.

Terminating threads is explained here: How do I terminate a thread in C++11?

And close event handling in GLFW: http://www.glfw.org/docs/latest/group__window.html#gaade9264e79fae52bdb78e2df11ee8d6a

There is no way to do that portably.

A quick solution on posix involves pthread_cancel . This will abruptly terminate the thread, leaking any resource currently held by the terminating thread.

For this reason is usually considered a bad practice, but in your case you are going to terminate the program anyway, so it might work for you. Consider redesigning your program by using lower-level I/O so that you can do a timed-out wait on the user input.

The relevant changes to your code, after including pthread.h , are:

Console::~Console()
{
     pthread_cancel( in_thread.native_handle() );
     in_thread.join();
}

//Get rid of the quit variable
void Console::thread_input()
{
     std::string input;
     while (true)
     {
        std::cin >> input;
        //Btw, you need a mutex here.
        input_queue.push(input);
     }
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM