我有一個應用程序依靠超時信號來執行一些阻塞操作。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