让我来描述我的情景:
我正在为教学系统开发基于命令行的概念验证,我正在用Python编写它。系统的工作原理是行为心理学。 我正在奖励用户(有特殊需要的孩子)以获得正确的答案,我正在给他们纠正错误答案的后果。 如果他们正在努力解答答案,我也需要提供答案提示。
这是我的应用程序的高级伪代码:
试验:
- 询问诸如“什么颜色是草?”之类的问题。
等待回答
一个。如果在n秒内未提供答案,则提示帮助提示(例如“Gr,Gree”)
湾如果在n + m秒内未提供答案,则会发出纠正后果。 (例如,“草的颜色是绿色的。让我们再试一次。”)并重复这个过程 C。如果在任何n或n + m时间内提供正确答案,请奖励学生并重复该过程 d。如果在任何n + m时间内提供了错误的答案,请发出纠正后果并重复试验。- 醇>
结束审判
所以这是我的观察和困境:
一旦我向学生发出问题,我正在等待事件自己发生,或等待我等待超时。我也应该在等待期间发出提示。
到目前为止,在我的主要流程中,我使用了两个threading.Timer
个对象,一个用于在n秒后发出提示,另一个用于在n + m时段内没有响应时发出纠正后果。
如果在n或n + m时间内发生任何类型的回答,我会取消定时器。
然而,我的问题与主要过程有关。如果答案等待超时,我还想取消等待答案。就像我取消计时器一样,如果我的最终无应答超时发生,我也想取消在命令行上等待输入。
我想有一个threading.Thread
(get_answer)和两个Timers(provide_hint,timeout_wait)。
线程get_answer正在等待来自命令行的响应。
如果n秒后没有应答,则第一个计时器(provide_hint)正在向用户发出提示。
如果在n + m秒的某段时间后没有回答,则第二个计时器(timeout_wait)正在取消线程(get_answer)。
如果答案正确或不正确,则线程get_answer可以取消两个计时器。
我在这里提出的问题是:
A)我的并发数据结构是否正确使用,您还有其他建议吗?
B)是否存在任何可能的死锁问题以及如何避免这些问题?
提前致谢。
答案 0 :(得分:1)
这是一个不使用线程的解决方案。它在Linux上进行了测试,但可能无处不在(但我不确定Windows)。它安排发送SIGALRM信号。
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
这不是最终解决方案,因为存在问题:如果用户已经键入了一行的一部分,SIGALRM将中断它,但到目前为止他输入的内容仍然在终端的读缓冲区中。它将是下一个raw_input()返回的部分内容。您可能必须以原始模式打开终端以避免这种情况。请参阅Confusion about raw vs. cooked terminal modes?。