如何在线程后继续代码?对这段代码的流程感到困惑
How to continue code after thread? Confused about the flow of this code
抱歉,我是编程新手,不太了解线程的工作原理。我的目标是为这个输入计时,我找到了一些代码来做到这一点。但是,我对该线程的结构感到困惑,因为如果您是 "too slow",程序将永远不会继续按需要打印 "checkpoint"。它只是有点……冻结……为什么卡住了?
import time
from threading import Thread
answer = None
def check():
# waits for user input for 3 seconds
for i in range(3):
time.sleep(1)
if answer != None:
return
print('too slow')
Thread(target = check).start()
answer = input("Input something: ")
print('checkpoint')
我试过的一件事是:
t = Thread(target = check)
t.start()
answer = input("Input something: ")
# also tried t.join()
if t.is_alive:
print('hi')
我试图通过引发和捕获异常来解决这个程序。但是,我无法捕获异常。我怎么抓住它? (或者我遇到的问题有其他解决方案吗?)
import time
from threading import Thread
answer = None
def check():
# waits for user input for 3 seconds
for i in range(3):
time.sleep(1)
if answer != None:
return
print('too slow')
# was hoping to catch this as an exception
raise TimeoutError
# starts new thread
Thread(target = check).start()
# prompts user for an input
answer = input("Input something: ")
print('checkpoint')
有什么好处:
当您在 3 秒内在输入提示中键入内容时,它会打印 "checkpoint" 并继续使用代码。
不好的地方:
如果您采用 "too long",程序会按预期打印 "too slow!",但随后它会停止执行代码,只是有点……冻结。因此,为了尝试解决此问题,我希望引发超时错误然后捕获它,但我不知道如何捕获它。这没有发现错误:
try:
Thread(target = check).start()
except:
pass
这也不是:
try:
answer = input("Input something: ")
except:
pass
我能得到一些帮助吗?谢谢!
编辑:忘了说我正在使用 linux 所以我的应用程序的很多解决方案都不适合我,比如 msvcrt 或键盘。为 Linux 工作的模块似乎不是 "non-blocking."
您应该将这两个线程视为两个独立的程序,但共享相同的变量。
线程 1 包含代码中未缩进的所有内容。它启动一个线程,然后等待用户输入,然后打印 "checkpoint"。那就大功告成了。
线程 2 由函数 check.
组成,它检查变量是否不是 None。如果发生这种情况,它就完成了。如果这在三秒钟内没有发生,它会打印 "too slow" 现在它已经完成了。
两个线程都"knows" 另一个线程在做什么,除了它们共享一个变量,answer.
当所有线程都完成时,整个程序将退出。
就是这样。那就是你写的。因此,如果您键入内容,程序将退出,因为线程 1 将始终在您键入内容后退出。一旦线程 2 发现变量不是 None,它就会退出。
如果您不输入任何内容,线程 1 将永远坐在那里等待您。这就是输入函数的工作原理。线程 2 将在 3 秒或更短时间后退出,但这不会影响线程 1。
您不能从一个线程向另一个线程抛出异常。所以你不能从线程 2 抛出异常并让线程 1 处理它。
您是否尝试过在消息 "too slow" 出现后键入内容?当您这样做时,线程 1(以及您的程序)将退出。
最重要的是,在这种情况下您不能使用输入函数,因为该函数会阻塞其线程流,直到用户键入内容。任何其他线程都无法使其继续。
免责声明:这并没有回答问题,但如果您想知道我是如何解决 "INPUT" 问题的,这里是我对问题的解决方案。
实际上我找到了一些有用的东西!这有点奇怪,但它适用于我正在尝试做的事情,感谢@rayryeng 在这里的回答:detect key press in python?.
问题陈述:当按下'enter'时继续执行程序,如果输入时间过长则超时。这正是这样做的,尽管它在控制台上显示得很奇怪……PS。我必须在我的终端中将此 运行 作为 'sudo' ,否则无论出于何种原因,它都无法在我的临时文件中使用。
import curses
import os
from time import time, sleep
def main(win):
win.nodelay(True) # True turns on "non-blocking"
key=""
win.clear()
win.addstr("Please press 'Enter' to continue:")
start_time = time()
while 1:
end_time = time()
try:
if end_time-start_time > 5: # 5 seconds
return 'You are too slow!'
else:
key = win.getkey()
if key == os.linesep:
return 'OK. Continuing on...'
except Exception as e:
# No input
pass
p = curses.wrapper(main)
print(p) #-> either 'You are too slow!' or 'OK. Continuing on...'
我想如果你真的想存储输入,你可以将它修改成这样:
def main(win):
win.nodelay(True) # True turns on "non-blocking"
key=""
win.clear()
win.addstr("Please press 'Enter' to continue:")
start_time = time()
while 1:
end_time = time()
try:
if end_time-start_time > 5: # 5 seconds
return 'You are too slow!'
else:
key = win.getkey() # gets a single char
if key: # == os.linesep:
return str(key) # returns that single char
except Exception as e:
# No input
pass
p = curses.wrapper(main)
print(p) #-> either 'You are too slow!' or character entered
如果你想存储更多字符,你可以这样做(请注意,它还会在结果字符串中存储 "enter" 键):
导入诅咒
导入 os
从时间导入时间,睡眠
def main(win):
win.nodelay(True) # True turns on "non-blocking"
key=""
win.clear()
win.addstr("Please press 'Enter' to continue:")
start_time = time()
result = key # empty string
while 1:
end_time = time()
try:
if end_time-start_time > 5: # 5 seconds
return 'You are too slow!'
else:
key = win.getkey() # gets single char
result = result + str(key) # adds characters to the empty string
if key == os.linesep: # "new line"
return result
except Exception as e:
# No input
pass
p = curses.wrapper(main)
print(p) #-> either 'You are too slow!' or characters entered
抱歉,我是编程新手,不太了解线程的工作原理。我的目标是为这个输入计时,我找到了一些代码来做到这一点。但是,我对该线程的结构感到困惑,因为如果您是 "too slow",程序将永远不会继续按需要打印 "checkpoint"。它只是有点……冻结……为什么卡住了?
import time
from threading import Thread
answer = None
def check():
# waits for user input for 3 seconds
for i in range(3):
time.sleep(1)
if answer != None:
return
print('too slow')
Thread(target = check).start()
answer = input("Input something: ")
print('checkpoint')
我试过的一件事是:
t = Thread(target = check)
t.start()
answer = input("Input something: ")
# also tried t.join()
if t.is_alive:
print('hi')
我试图通过引发和捕获异常来解决这个程序。但是,我无法捕获异常。我怎么抓住它? (或者我遇到的问题有其他解决方案吗?)
import time
from threading import Thread
answer = None
def check():
# waits for user input for 3 seconds
for i in range(3):
time.sleep(1)
if answer != None:
return
print('too slow')
# was hoping to catch this as an exception
raise TimeoutError
# starts new thread
Thread(target = check).start()
# prompts user for an input
answer = input("Input something: ")
print('checkpoint')
有什么好处: 当您在 3 秒内在输入提示中键入内容时,它会打印 "checkpoint" 并继续使用代码。
不好的地方: 如果您采用 "too long",程序会按预期打印 "too slow!",但随后它会停止执行代码,只是有点……冻结。因此,为了尝试解决此问题,我希望引发超时错误然后捕获它,但我不知道如何捕获它。这没有发现错误:
try:
Thread(target = check).start()
except:
pass
这也不是:
try:
answer = input("Input something: ")
except:
pass
我能得到一些帮助吗?谢谢!
编辑:忘了说我正在使用 linux 所以我的应用程序的很多解决方案都不适合我,比如 msvcrt 或键盘。为 Linux 工作的模块似乎不是 "non-blocking."
您应该将这两个线程视为两个独立的程序,但共享相同的变量。
线程 1 包含代码中未缩进的所有内容。它启动一个线程,然后等待用户输入,然后打印 "checkpoint"。那就大功告成了。
线程 2 由函数 check.
组成,它检查变量是否不是 None。如果发生这种情况,它就完成了。如果这在三秒钟内没有发生,它会打印 "too slow" 现在它已经完成了。
两个线程都"knows" 另一个线程在做什么,除了它们共享一个变量,answer.
当所有线程都完成时,整个程序将退出。
就是这样。那就是你写的。因此,如果您键入内容,程序将退出,因为线程 1 将始终在您键入内容后退出。一旦线程 2 发现变量不是 None,它就会退出。
如果您不输入任何内容,线程 1 将永远坐在那里等待您。这就是输入函数的工作原理。线程 2 将在 3 秒或更短时间后退出,但这不会影响线程 1。
您不能从一个线程向另一个线程抛出异常。所以你不能从线程 2 抛出异常并让线程 1 处理它。
您是否尝试过在消息 "too slow" 出现后键入内容?当您这样做时,线程 1(以及您的程序)将退出。
最重要的是,在这种情况下您不能使用输入函数,因为该函数会阻塞其线程流,直到用户键入内容。任何其他线程都无法使其继续。
免责声明:这并没有回答问题,但如果您想知道我是如何解决 "INPUT" 问题的,这里是我对问题的解决方案。
实际上我找到了一些有用的东西!这有点奇怪,但它适用于我正在尝试做的事情,感谢@rayryeng 在这里的回答:detect key press in python?.
问题陈述:当按下'enter'时继续执行程序,如果输入时间过长则超时。这正是这样做的,尽管它在控制台上显示得很奇怪……PS。我必须在我的终端中将此 运行 作为 'sudo' ,否则无论出于何种原因,它都无法在我的临时文件中使用。
import curses
import os
from time import time, sleep
def main(win):
win.nodelay(True) # True turns on "non-blocking"
key=""
win.clear()
win.addstr("Please press 'Enter' to continue:")
start_time = time()
while 1:
end_time = time()
try:
if end_time-start_time > 5: # 5 seconds
return 'You are too slow!'
else:
key = win.getkey()
if key == os.linesep:
return 'OK. Continuing on...'
except Exception as e:
# No input
pass
p = curses.wrapper(main)
print(p) #-> either 'You are too slow!' or 'OK. Continuing on...'
我想如果你真的想存储输入,你可以将它修改成这样:
def main(win):
win.nodelay(True) # True turns on "non-blocking"
key=""
win.clear()
win.addstr("Please press 'Enter' to continue:")
start_time = time()
while 1:
end_time = time()
try:
if end_time-start_time > 5: # 5 seconds
return 'You are too slow!'
else:
key = win.getkey() # gets a single char
if key: # == os.linesep:
return str(key) # returns that single char
except Exception as e:
# No input
pass
p = curses.wrapper(main)
print(p) #-> either 'You are too slow!' or character entered
如果你想存储更多字符,你可以这样做(请注意,它还会在结果字符串中存储 "enter" 键):
导入诅咒 导入 os 从时间导入时间,睡眠
def main(win):
win.nodelay(True) # True turns on "non-blocking"
key=""
win.clear()
win.addstr("Please press 'Enter' to continue:")
start_time = time()
result = key # empty string
while 1:
end_time = time()
try:
if end_time-start_time > 5: # 5 seconds
return 'You are too slow!'
else:
key = win.getkey() # gets single char
result = result + str(key) # adds characters to the empty string
if key == os.linesep: # "new line"
return result
except Exception as e:
# No input
pass
p = curses.wrapper(main)
print(p) #-> either 'You are too slow!' or characters entered