ThreadPoolExecutor执行完任务后偶尔冻结,如何确保稳定运行?
解决ThreadPoolExecutor执行后程序冻结的问题
以下是针对你遇到的线程池执行后程序冻结问题的具体解决方法:
给网络请求强制添加超时限制
程序冻结大概率是因为某个线程的网络请求卡住(比如服务器无响应、网络波动),导致线程池无法正常关闭。你需要确保bl.checkLink和bl.generateNewLinks中的HTTP请求都带有超时参数。如果ballotpedialinks模块支持传入超时,直接修改调用:a = bl.checkLink(page, timeout=10) # 设置10秒超时如果模块不支持,需要修改模块内部的请求逻辑(比如用
requests库时加上timeout=(3, 10)),强制终止长时间无响应的请求。捕获线程函数内的所有异常
线程函数中未捕获的异常会干扰线程池的正常回收逻辑,必须给线程函数加上完整的异常捕获:def threadFunction(data): try: page = data[0] counter = data[1] a = bl.checkLink(page) print(a[0]) if a[0] == '': links = bl.generateNewLinks(page, state) for link in links: a = bl.checkLink(link) if a[0] != '': print(f'{a[0]} is a fixed link') break except Exception as e: print(f"处理链接{data[0]}时出错: {str(e)}")降低线程数,避免资源过载
32个并发线程容易触发目标网站的反爬限流,也会消耗过多本地网络资源,导致请求挂起。建议把线程数调整到10-16之间测试:quickRun(12) # 调整并发线程数改用
submit+as_completed替代mappool.map会等待所有任务完成,而as_completed可以逐个处理完成的任务,更易监控异常和超时,避免整体阻塞:from concurrent.futures import ThreadPoolExecutor, as_completed def quickRun(threads): with ThreadPoolExecutor(threads) as pool: futures = [pool.submit(threadFunction, item) for item in data[0:-1]] for future in as_completed(futures): try: future.result() # 捕获单个任务的异常 except Exception as e: print(f"任务执行出错: {str(e)}")检查
ballotpedialinks模块的资源泄漏
确认bl.checkLink和bl.generateNewLinks内部是否正确释放了网络连接、文件等资源。比如如果用了requests.Session,要确保关闭会话;如果打开了文件,要用with块管理,避免资源泄漏导致线程池无法正常回收。
内容的提问来源于stack exchange,提问作者John Corn
相关产品推荐
相关产品推荐

