views:

234

answers:

3

Hi,

My program has a main thread that takes command input from a user. Separately, it has potentially multiplie (at least 1) worker threads churning data in the background.

The user is able to terminate the program using a command by typing into the console. However, when the data churning is done, the main thread is still blocking waiting for user input and hence the program does not terminate.

What I would like to know is how to write the terminate command, "q\n", into the std::cin from a worker thread so that the blocking command input thread (also the main thread) will terminate. Or would this be a bad thing to do? I've tried the below but the program simply hangs or not able to write to the std::cin, not sure why.

static ACE_THR_FUNC_RETURN worker( void *p) {
 .....
    if (_this->m_num_threads_done == _this->m_threads.size()) {
        fputs("q\n", stdin);
    }

}

on the main thread, this is called from main:

void runEventLoop()
{
    printWelcomeMessage();

    char buffer[MAXC];
    while( !m_exitLoop )
    {
        std::cin.getline(buffer, MAXC);
        if( std::cin.eof() )
            break;
        handleCommand( buffer );
    }
}

would someone please advise on what I'm doing wrong here or otherwise suggest a better solution for what I'm trying to accomplish?

thanks

+1  A: 

A "nice" solution would be to write your own input function, that is non-blocking and checks if a character is pressed, else idles. In that loop you could have a termination check.

Read about non-blocking keyboard input.

Apart from that, there are several platform dependent solutions, depending on your threads library, and your operating system. If you would expand your question with that info, we could suggest something.

Kornel Kisielewicz
ideally i'd like to have the solution cross-platformed.. but i'm using pthreads on mac os x snow leopard
hk_programmer
+2  A: 

On Unix, when you need a thread to wait for multiple things (for example, a character on std::in and a command from a worker thread to communicate that it is shutting down) you use select()... You could create a pipe with the pipe() system call and the worker thread could write to it when it's exiting... The main thread that is waiting currently on cin could call select() on both to block, then react appropriately to either when it's woken up..

On Windows, you can probably use WaitForMultipleObjects() for the same purpose.

dicroce
do u happen to have any sample code or pointers to them handy? if it helps i'm using a networking package called ACE (but once i get the general idea it should be easy for me to search on how to do it on ACE)
hk_programmer
A: 

Your problem is that you are using a blocking call in the shape of getline(). The C++ Standard does not provide any non-blocking I/O mechanisms for reading standard input, so your best bet is to use something OS or platform specific to poll the keyboard.

anon