有没有办法让产生新线程的父级捕获产生的线程异常?以下是我想要完成的一个真实的基本示例.当引发Exception时它应该停止计数,但我不知道如何捕获它.异常线程安全吗?我希望能够使用该Subprocess模块,但我不习惯使用Python 2.3,我不知道如何做到这一点.可能使用该threading模块?
import time
import thread
def test():
try:
test = thread.start_new_thread(watchdog, (5,))
count(10)
except:
print('Stopped Counting')
def count(num):
for i in range(num):
print i
time.sleep(1)
def watchdog(timeout):
time.sleep(timeout)
raise Exception('Ran out of time')
if __name__ == '__main__':
test()
Run Code Online (Sandbox Code Playgroud)
UPDATE
我的原始代码有点误导.它真的在寻找更像这样的东西:
import time
import thread
import os
def test():
try:
test = thread.start_new_thread(watchdog, (5,))
os.system('count_to_10.exe')
except:
print('Stopped Counting')
def watchdog(timeout):
time.sleep(timeout)
raise Exception('Ran out of time')
if __name__ == '__main__':
test()
Run Code Online (Sandbox Code Playgroud)
我试图创建一个看门狗来杀死os.system调用,如果该程序由于某种原因挂起.
我正在尝试创建一个看门狗类,它将在指定时间后抛出异常:
from threading import Timer
from time import sleep
class watchdog():
def _timeout(self):
#raise self
raise TypeError
def __init__(self):
self.t = Timer(1, self._timeout)
def start(self):
self.t.start()
try:
w = watchdog()
w.start()
sleep(2)
except TypeError, e:
print "Exception caught"
else:
print "Of course I didn't catch the exception"
Run Code Online (Sandbox Code Playgroud)
该异常未被捕获,因为该异常是从完全不同的上下文引发的,因此我们将看到最后一条消息。
我的问题是,如何修改代码,以便捕获异常?
from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED
def div_zero(x):
print('In div_zero')
return x / 0
with ThreadPoolExecutor(max_workers=4) as executor:
futures = executor.submit(div_zero, 1)
done, _ = wait([futures], return_when=ALL_COMPLETED)
# print(done.pop().result())
print('Done')
Run Code Online (Sandbox Code Playgroud)
上面的程序将完全运行,没有任何错误消息。
仅当您显式调用future.result()或时future.exception()(如我在注释行中所做的那样),您才能获得异常。
我想知道为什么这个Python模块即使隐藏了问题也选择了这种行为。因此,我花费了数小时来调试编程错误(在类中引用了不存在的属性),否则该错误将在程序异常崩溃(例如Java)时非常明显。
我有多个正在运行的Process线程,我想将它们与所有 timeout参数一起加入。我知道,如果没有超时的必要,我可以写:
for thread in threads:
thread.join()
Run Code Online (Sandbox Code Playgroud)
我想到的一种解决方案是使用将所有线程连接在一起的主线程,然后尝试连接该线程。但是,我在Python中收到以下错误:
AssertionError: can only join a child process
Run Code Online (Sandbox Code Playgroud)
我的代码如下。
def join_all(threads):
for thread in threads:
thread.join()
if __name__ == '__main__':
for thread in threads:
thread.start()
master = multiprocessing.Process(target=join_all, args=(threads,))
master.start()
master.join(timeout=60)
Run Code Online (Sandbox Code Playgroud)