
Question:
Let me describe my scenario:
I am developing a command line-based proof-of-concept for the instructional system, and I am writing it in Python. System works on the principles of behavioral psychology. I am rewarding users (children with special needs) for correct answers, and I am giving them correcting consequences for the wrong answers. I am also needing to provide hints to answers if they are struggling with answers.
Here is a high level pseudo code for my application:
<blockquote> <h2>Trial:</h2> <ol><li>Ask question such as 'What color is grass?' </li> <li>wait for answer<br /> a. If answer not provided within n seconds issue helping hint (e.g. "Gr, Gree")<br /> b. If answer is not provided within n+m seconds issue a corrective consequence. (e.g.,"Color of the grass is green.Let's try it again. ") and repeat the process<br /> c. If correct answer is provided during any n or n+m time praise the student and repeat the process.<br /> d. If the incorrect answer is provided during any of the n+m time, issue a corrective consequence and repeat the trial.
</li> <li>Conclude the trial
</li> </ol></blockquote>So here is my observation and a dilemma:
Once I issue a question to student, I am waiting for events to happen on their own, or for my waiting to time out. I am also supposed to issue a hint during the wait period.
So far, in my main flow I used two threading.Timer
objects, one to issue hint after n seconds and another one to issue corrective consequence if the answer never happens during the n+m period.
If answer happens of any kind during n or n+m time, I cancel the timers.
My question, however, is related to the main process. I also want to cancel the waiting on the answer if the answer waiting time-out happen. Just as I cancel timers, I also want to cancel waiting on the command line for the input if my final no-answer timeout occurs.
I am thinking to have one threading.Thread
(get_answer) and two Timers (provide_hint, timeout_wait).
Thread get_answer is waiting on a response from a command line.
First timer (provide_hint) is giving a hint to user if there is no answer after n seconds.
Second timer (timeout_wait) is canceling out the thread (get_answer) if no answer happens after some period of n+m seconds.
Thread get_answer can cancel both timers if the answer happens be it correct or incorrect.
<strong>Questions I have here are:</strong>
A) Are my concurrent data structures correctly used and do you have any other suggestions?
B) Are there any possible deadlock issues and how to avoid them?
Thanks in advance.
Answer1:Here is a solution without using threads. It was tested on Linux, but probably works everywhere (but I'm unsure about Windows). It arranges for a SIGALRM signal to be delivered.
import signal
class Alarm(Exception):
pass
def stop_me(*args):
raise Alarm
signal.signal(signal.SIGALRM, stop_me)
def raw_input_with_timeout(timeout):
try:
signal.alarm(timeout) # number in seconds
try:
return raw_input()
finally:
signal.alarm(0) # stop the alarm
except Alarm:
return "alarm!" # or anything
It's not a final solution because there are issues: if the user already typed part of a line, a SIGALRM will interrupt it, but what he typed so far remains in the read buffer of the terminal. It will be part of what the next raw_input() returns. You may have to turn the terminal in raw mode to avoid that. See <a href="https://stackoverflow.com/questions/13104460/c-confusion-about-raw-vs-cooked-terminal-modes" rel="nofollow">Confusion about raw vs. cooked terminal modes?</a> .