Skip to main content
gamedev.net
🔒 Locked

Problems terminating cin-thread safely

Started by _0D_0A 9 replies 1.1k views
Original Post
_0D_0A
_0D_0A
I'm doing a little Quiz program (C++) using console windows and I'm suffering a hard time terminating an ordinary cin function. I want to let the the user write for a specified time, but when the time is up I want to terminate the cin function. I realized that I'd probably would have to solve the issue using multithreading (one thread keeping track of the time and one handling the user input (cin.getline())). As the input-handling function mostly stands still it doesn't know when the time is up and it can therefore not terminate itself until the user has written something. I've tried to terminate the thread using TerminateThread(), but I was sceptical it would work properly (and it obviously didn't). I know try to put an '\n' to the cin-buffer from the time-handling thread using cin.rdbuf()->sputc() so that the cin.getline() in the cin-handling thread quits and then checks if it should terminate, but it still doesn't quit. Well, maybe I can't use the function as I'd hoped, I'm no expert at iostream. Does anyone know how I can solve my issue the easiest way?
Penance
Penance
Sorry, mis-post.
frob
frob
Since you're using Windows consoles, you can use the Windows API console functions.

For line oriented stuff, you're probably interested in PeekConsoleInput, ReadConsoleInput, or maybe just ReadConsole.

For single letter oreinted stuff, you should probably just be waiting for a keyboard event, such as the WM_CHAR notification.

Both of those can be done single-threaded.
frob
frob
Quote:
Original post by Penance
Try getting one character at a time and adding it to a buffer over and over until your time limit has been reached?


That's a tight polling loop. It will eat all the CPU and is generally considered a bad practice.

There are a variety of waiting and sleeping functions available in Windows that won't eat all the CPU time but fill the requirements.
Penance
Penance
Damn, you're fast. I went back and corrected myself and you'd already quoted my bad suggestion muahahahaa
_0D_0A
_0D_0A
Quote:
Original post by frob
Since you're using Windows consoles, you can use the Windows API console functions.

For line oriented stuff, you're probably interested in PeekConsoleInput, ReadConsoleInput, or maybe just ReadConsole.

For single letter oreinted stuff, you should probably just be waiting for a keyboard event, such as the WM_CHAR notification.

Both of those can be done single-threaded.


That sounds pretty good, but I'm not sure how to use it. Will ReadConsoleInput() automaticly read what has been written without having a cin active or do they have to "cooperate" somehow? — If you have time, I'd love an example.
Penance
Penance
Do you want to keep whatever input the user has typed in up until time expired? Or if they havn't submitted an answer do you just assume it is incorrect?

If you don't care about what they've typed when time expires, you can just terminte the input thread.
_0D_0A
_0D_0A
Quote:
Original post by Penance
Do you want to keep whatever input the user has typed in up until time expired? Or if they havn't submitted an answer do you just assume it is incorrect?

If you don't care about what they've typed when time expires, you can just terminte the input thread.


The problem is that I can't, if I terminate a thread that's running cin 7 times the process stops handling all keyboard events (oddly). I have assumed that it has to do with the unsafe thread termination.
Penance
Penance
Ok, as far as "easy" why not simulate keyboard input?
Checkout INPUT and SendInput() on MSDN. This way you can send your newline character to cin like you wanted to do originally.

Another option might be to just let the input thread always run and use a shared variable between the two threads. Put the input into a buffer and let the main thread just check that and provide feedback to the user as appropriate ie: "Wait until I ask the question, please." or "Time's up, you didn't provide an answer, sorry"
_0D_0A
_0D_0A
Quote:
Original post by Penance
Ok, as far as "easy" why not simulate keyboard input?
Checkout INPUT and SendInput() on MSDN. This way you can send your newline character to cin like you wanted to do originally.

Another option might be to just let the input thread always run and use a shared variable between the two threads. Put the input into a buffer and let the main thread just check that and provide feedback to the user as appropriate ie: "Wait until I ask the question, please." or "Time's up, you didn't provide an answer, sorry"


Phew, thanks! Found keybd_event() when I checked som info about SendInput(), which did the job perfectly for me. I've now got both easy AND working code. Thanks a lot!
Penance
Penance
np, glad I could help.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.