3

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
    std::cin is the _input_ stream in c++. You can read from it, not write to it. Could you be talking about stdout? – Dima Jan 15 '10 at 15:03
  • well in unix you can redirect output to input. so programmatically i thought you should be able to do it as well.. but i am talking about stdin – hk_programmer Jan 15 '10 at 15:06
  • Worker threads shouldn't be making decisions about program flow control, that should be handled by the main thread which is listening for user input. If you can post code for your main thread then we can suggest a more modular approach – Sam Post Jan 15 '10 at 15:11
  • You seem to be talking about the pseudo terminal connected to std::cin. – Don Jan 15 '10 at 15:15
  • Sam: posted main thread loop. all i'm looking for is to modify the loop so that the main thread knows when all worker threads are done and have to options to exit itself. So i dont have to sit there and type the terminate command each time. – hk_programmer Jan 15 '10 at 15:19

2 Answers2

3

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
  • 45,396
  • 28
  • 101
  • 140
  • 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 Jan 15 '10 at 15:12
2

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.

Community
  • 1
  • 1
Kornel Kisielewicz
  • 55,802
  • 15
  • 111
  • 149