我有一个应用程序依靠超时信号来执行一些阻塞操作。Python线程中超时信号的替代方案
例如:
def wait_timeout(signum, frame):
raise Exception("timeout")
signal.signal(signal.SIGALRM, wait_timeout)
signal.setitimer(signal.ITIMER_REAL, 5)
try:
while true:
print("zzz")
sleep(1)
except Exception as e:
# timeout
print("Time's up")
使用相同的方法现在,我已经实现了多线程,但所有的线程我得到ValueError: signal only works in main thread
。
我假设信号超时的方法不适用于线程。
不幸的是我不能使用这样的事情:
timeout = 5
start = time.time()
while true:
print("zzz")
sleep(1)
if time.time() <= start+timeout:
print("Time's up)
break
由于操作while循环可能会阻止并可能永远持续下去,因此循环可能永远达不到的,如果条款。
问:我该如何在线程中实现一个超时,就像我曾经用信号做过的那样?
编辑:我碰到过this blog post,在python中显示了类似的解决方案,用于JavaScript中的setTimeout()
。我认为这可能是一个可能的解决方案,但我真的不知道如何使用它。
EDIT2:我开始在主线程如下:
p = Popen(["tool", "--param", arg], stdin=PIPE, stdout=PIPE, stderr=STDOUT)
t = Thread(target=process_thread, daemon=True, args=(p,arg1,arg2))
t.start()
的process_thread
函数处理tool
的标准输出,通过执行以下操作:
for line in p.stdout:
# process line of the processes stdout
该过程可以永远拿走,例如一旦tool
不产生任何输出。我只想要tool
的输出,比方说5秒,所以for循环需要在特定超时后中断。
这就是我使用的信号,但显然他们不能在线程中工作。
edit3:我已经创建了一个更精细和准确的示例,说明如何在线程中使用信号。 See the gist here
你是如何开始你的线程?当你定义它们时,你是否设置了'daemon = True'?如果是这样,那么当主线程死亡时,这些线程将被终止。那是你想要做什么? – Billy
是的,我以deamons开头,我会在一分钟内编辑OP。不,那不是我正在尝试的,我会尽力在OP中更好地解释它。 – SaAtomic
我已经更新了OP @Billy – SaAtomic