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 ...
随机推荐
- pipenv 管理虚拟环境
pipenv --python 3.6 创建虚拟环境 vim Pipfile —> 修改源 为阿里云镜像 https://mirrors.aliyun.com/pypi/simple [pack ...
- Jenkins连接Git仓库时候报错Permission denied, please try again.
一.连接GIT仓库报错 Failed to connect to repository : Command : stdout: stderr: Permission denied, please tr ...
- 用户交互Scanner的用法
Java用户交互的目的是实现程序与人的交互:一般通过Scanner来获取用户的输入:java.util.Scanner 是Java5的新特征. 基本语法: Scanner s=new Scanner( ...
- 使用GCP_EC2云服务器搭部署网络服务
首先,在此阿里云/腾讯云/华为云购买一个云服务器推荐使用阿里云的 首先链接你的VPS,可以使用X-shell / Putty / SecureCRTPortable 等SSH链接工具 注意:如果不知道 ...
- Alpha版本1
这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/2019autumnsystemanalysisanddesign/ 这个作业要求在哪里 https:// ...
- 如何下载Youtube的4K视频?这里有4款软件, 哪个适合你?
数字电影的最新分辨率标准是4k,4K分辨率的视频具有高图像清晰度质量.更好的快速动作.更大的投影表面可见度和更详细的图像质量等优点,受到了广大视频爱好者的好评.作为当前最火热的视频分享网站,YouTu ...
- Rust中的枚举及模式匹配
这个enum的用法,比c要强,和GO类似. enum Coin { Penny, Nickel, Dime, Quarter, } fn value_in_cents(coin: Coin) -> ...
- django学习-视图练习
写一个真正有用的视图 每个视图必须要做的只有两件事: 返回一个包含被请求页面内容的HttpResponse对象,或抛出一个异常,比如Http404. 至于你还想干些什么,随便你. 你的视图可以从数据库 ...
- Excel-统计函数
1.Count系列函数 COUNT 数字个数----下面结果为 4 counta 非空的字数 ----下面为6 COUNTBLANK ------非空个数 ---- 下面为9 如何将字符串形式的数字 ...
- MacBook安装WIN7开机黑屏的解决办法
同事的一台Macbook,全盘用diskgenius格式化为MBR分区,支持BIOS启动,安装ghost版本的WIN7,开机黑屏,看了网上的帖子没有用,插入启动盘按option键选择从优盘启动,用di ...