""" 模拟超时跳过逻辑 文件列表:file_A 正常(2s),file_B 超时(20s),file_C 正常(2s) 期望结果:B 超时后直接跳到 C,总耗时约 TIMEOUT+2s 而不是 20+2+2s """ import time import threading import concurrent.futures from concurrent.futures import ThreadPoolExecutor EXTRACT_TIMEOUT = 5 # 测试用 5 秒超时 def fake_extract(file_name, cancel_event): """模拟抽取:file_B 故意睡 20 秒""" sleep_time = 20 if file_name == "file_B" else 2 print(f" [{file_name}] 开始抽取,预计耗时 {sleep_time}s") for _ in range(sleep_time * 10): time.sleep(0.1) if cancel_event.is_set(): print(f" [{file_name}] 收到取消信号,退出不写 JSON") return {"file": file_name, "status": "timeout"} print(f" [{file_name}] 抽取完成,写 JSON") return {"file": file_name, "status": "ok"} def run(): files = ["file_A", "file_B", "file_C"] results = [] t_start = time.time() with ThreadPoolExecutor(max_workers=2) as pool: future_meta = [] for f in files: evt = threading.Event() fut = pool.submit(fake_extract, f, evt) future_meta.append((fut, f, evt)) for fut, f, evt in future_meta: try: result = fut.result(timeout=EXTRACT_TIMEOUT) results.append(result) except concurrent.futures.TimeoutError: evt.set() print(f" [{f}] 超时,跳过,记录 fault 文件") results.append({"file": f, "status": "timeout"}) total = time.time() - t_start print(f"\n总耗时: {total:.1f}s") print("结果汇总:") for r in results: print(f" {r}") if __name__ == "__main__": run()