python利用ThreadPoolExecutor实现有任务异常,就终止线程池中的所有剩余任务
先描述一下场景:
我有一批任务需要放入线程池中去处理,但是一旦线程池中有1个任务出现了异常(抛了Exception)就将线程中尚未开始的任务全部取消不执行。
需要说明的是正在执行的任务因为无法撤销,所以正在执行的任务只能继续执行,等他执行完成。
import queue
from concurrent.futures import ThreadPoolExecutor, as_completed, wait, ALL_COMPLETED, FIRST_EXCEPTION def send_cmd(ip, exec_queue):
# 如果消息队列中消息不为空,说明已经有任务异常了
if not exec_queue.empty():
return
try:
# 需要执行的主任务
except Exception as e:
# 如果任务异常了就在队列中写入一个消息,用于锁住线程池
exec_queue.put("Termination")
# 此处一定要将异常再次抛出,否则主线程池无法捕获异常,会统一认定为任务已被取消
raise Exception(e) # 此处使用消息队列作为线程池锁,避免在第一个任务异常发生后到主线程获知中间仍然有任务被发送执行
exec_queue = queue.Queue()
with ThreadPoolExecutor(max_workers=thread_pool_size) as executor:
task_dict, task_list = {}, []
# 将任务全部放入线程池中
for ip in ip_list:
task = executor.submit(send_cmd, ip, exec_queue)
task_dict[task] = ip
task_list.append(task)
# 等待第一个任务抛出异常,就阻塞线程池
wait(task_list, return_when=FIRST_EXCEPTION)
# 反向序列化之前塞入的任务队列,并逐个取消
for task in reversed(task_list):
task.cancel()
# 等待正在执行任务执行完成
wait(task_list, return_when=ALL_COMPLETED) for task in task_list:
if task_dict.get(task):
if "finished returned NoneType" in str(task) or task.cancelled():
print("{}被取消".format(task_dict.get(task)))
elif "finished raised Exception" in str(task):
print("{}执行异常".format(task_dict.get(task)))
else:
print("{}执行成功".format(task_dict.get(task)))
加入队列作为线程池锁,是因为在实际测试中发现,如果所有任务被一次性塞入线程池后,当第一个异常发生到,异常被主线程池捕获中间,仍然会有任务被执行,具体数量依据任务执行的快慢,数量也是不定的,但至少会有1个,属于必现情况。加入线程池,可以有效阻止这类问题的发生。
python利用ThreadPoolExecutor实现有任务异常,就终止线程池中的所有剩余任务的更多相关文章
- Java线程池ThreadPoolExecutor使用和分析(三) - 终止线程池原理
相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...
- ThreadPoolExecutor之二:jdk实现的线程池介绍
一 简介 线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的.在jdk1.5之后这一情况有了很大的改观.Jdk1.5之后加入了java.uti ...
- c#线程池中的异常
static void Main(string[] args) { //写日志 //使用线程池 ; i < ; i++) { ThreadPool.QueueUserWorkItem(new W ...
- ThreadPoolExecutor线程池中线程不能超过核心线程数量的问题
int arg1=2;//核心线程 int arg2=40;//最大线程数量 int arg3=100;//空余保留时间 ThreadPoolExecutor pool=new ThreadPoolE ...
- 线程池中状态与线程数的设计分析(ThreadPoolExecutor中ctl变量)
目录 预备知识 源码分析 submit()源码分析 shutdownNow()源码分析 代码输出 设计目的与优点 预备知识 可以先看下我的另一篇文章对于Java中的位掩码BitMask的解释. 1.一 ...
- 【高并发】通过ThreadPoolExecutor类的源码深度解析线程池执行任务的核心流程
核心逻辑概述 ThreadPoolExecutor是Java线程池中最核心的类之一,它能够保证线程池按照正常的业务逻辑执行任务,并通过原子方式更新线程池每个阶段的状态. ThreadPoolExecu ...
- Python之路第十一天,高级(3)-线程池
线程池 简单的线程池的实现: import queue import threading import time class ThreadPool(object): def __init__(self ...
- Java8线程池ThreadPoolExecutor底层原理及其源码解析
小侃一下 日常开发中, 或许不会直接new线程或线程池, 但这些线程相关的基础或思想是非常重要的, 参考林迪效应; 就算没有直接用到, 可能间接也用到了类似的思想或原理, 例如tomcat, jett ...
- 从源码角度来分析线程池-ThreadPoolExecutor实现原理
作为一名Java开发工程师,想必性能问题是不可避免的.通常,在遇到性能瓶颈时第一时间肯定会想到利用缓存来解决问题,然而缓存虽好用,但也并非万能,某些场景依然无法覆盖.比如:需要实时.多次调用第三方AP ...
随机推荐
- 微信小程序的线程架构
小程序的线程架构 每个小程序包含一个描述整体程序的app实例和多个描述页面的page. 其中app由3个文件构成: app.json 公共配置文件 app.wxss 公共样式文件 app.js 主体逻 ...
- [20190509]rman备份的疑问5.txt
[20190509]rman备份的疑问5.txt --//别人跟我提到的rman备份问题,我开始以为是assm与mssm的问题,实际测试情况不是.--//开始备份时生成的备份集文件很大,以后会回缩(对 ...
- 【IDE_IntelliJ IDEA】idea主题设置
参考博文: IDEA 炫酷的主题字体颜色设置 idea主题下载
- layer.js的一些常用的技巧
我们在一些弹出框或者其他的一些表单的样式逻辑当中会用到layer的组件,针对我遇到的问题做个小结 1.在使用checkbox进行多选的时候,默认的layer会有一个对勾的样式,但是我们通常在做单选或者 ...
- Linux---文件压缩与解压缩命令
压缩格式: zip.gz.bz2.tar .tar.gz.tar.bz2.tar.xz.xz.z 最常用的是.tar.gz格式和.tar.bz2格式 1.zip格式 命令 说明 zip 压缩文件名 ...
- JS高阶---作用域面试
面试题1: ,答案为10 有一点需要明确:作用域是在定义编写代码时已经决定好的 面试题2: 结果1: 结果2: 首先在内部作用域找,没有 然后在全局作用域找,window没有,所以会报错 如果想找对象 ...
- 201871010104-陈园园 《面向对象程序设计(java)》第十五周学习总结
201871010104-陈园园 <面向对象程序设计(java)>第十五周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...
- Tkinter 鼠标键盘事件(一)
一: 鼠标事件 <Button-1> 鼠标左键单击 ...
- python27期day10:函数的动态参数、函数的注释、函数的名称空间、函数的嵌套、global(修改全局的)、nonlocal(修改局部的)、函数名的第一类对象及使用、作业题。
1.动态参数的作用: 能够接收不固定长度参数 位置参数过多时可以使用动态参数 * args是程序员之间约定俗称(可以更换但是不建议更换) * args获取的是一个元组 ** kwargs获取的是一个字 ...
- arm指令集图片