装一个钩子
(每道题开头都有同一段:六个来源 SOURCES,每项是 (名字, 要等的秒数, 字节数);fetch(name, wait, size) 睡 wait 秒后交回 size——「等」的时候别人能干活。)
(这一节的 fetch 多了一条:来源是「天气」时会抛 ValueError——线程里的异常怎么处理,就看它。)
threading.excepthook 是线程异常的统一出口:线程里没接住的异常都会经过它。装一个只记名字的钩子,看它记下了谁:
import threading, time
SOURCES = [("首页", 0.05, 1200), ("新闻", 0.08, 3400), ("图片", 0.03, 8800), ("视频", 0.10, 20000), ("论坛", 0.06, 2600), ("天气", 0.02, 300)]
def fetch(name, wait, size):
time.sleep(wait)
if name == "天气":
raise ValueError("来源挂了:" + name)
return size
caught = []
lock = threading.Lock()
def hook(args):
with lock:
caught.append(args.thread.name)
threading.excepthook = hook
ts = [threading.Thread(target=fetch, args=s, name=s[0]) for s in SOURCES]
for t in ts:
t.start()
for t in ts:
t.join()
print(str(len(caught)) + "/" + ",".join(caught))
全部评论