先描述一下场景:

我有一批任务需要放入线程池中去处理,但是一旦线程池中有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实现有任务异常,就终止线程池中的所有剩余任务的更多相关文章

  1. Java线程池ThreadPoolExecutor使用和分析(三) - 终止线程池原理

    相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...

  2. ThreadPoolExecutor之二:jdk实现的线程池介绍

    一 简介 线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的.在jdk1.5之后这一情况有了很大的改观.Jdk1.5之后加入了java.uti ...

  3. c#线程池中的异常

    static void Main(string[] args) { //写日志 //使用线程池 ; i < ; i++) { ThreadPool.QueueUserWorkItem(new W ...

  4. ThreadPoolExecutor线程池中线程不能超过核心线程数量的问题

    int arg1=2;//核心线程 int arg2=40;//最大线程数量 int arg3=100;//空余保留时间 ThreadPoolExecutor pool=new ThreadPoolE ...

  5. 线程池中状态与线程数的设计分析(ThreadPoolExecutor中ctl变量)

    目录 预备知识 源码分析 submit()源码分析 shutdownNow()源码分析 代码输出 设计目的与优点 预备知识 可以先看下我的另一篇文章对于Java中的位掩码BitMask的解释. 1.一 ...

  6. 【高并发】通过ThreadPoolExecutor类的源码深度解析线程池执行任务的核心流程

    核心逻辑概述 ThreadPoolExecutor是Java线程池中最核心的类之一,它能够保证线程池按照正常的业务逻辑执行任务,并通过原子方式更新线程池每个阶段的状态. ThreadPoolExecu ...

  7. Python之路第十一天,高级(3)-线程池

    线程池 简单的线程池的实现: import queue import threading import time class ThreadPool(object): def __init__(self ...

  8. Java8线程池ThreadPoolExecutor底层原理及其源码解析

    小侃一下 日常开发中, 或许不会直接new线程或线程池, 但这些线程相关的基础或思想是非常重要的, 参考林迪效应; 就算没有直接用到, 可能间接也用到了类似的思想或原理, 例如tomcat, jett ...

  9. 从源码角度来分析线程池-ThreadPoolExecutor实现原理

    作为一名Java开发工程师,想必性能问题是不可避免的.通常,在遇到性能瓶颈时第一时间肯定会想到利用缓存来解决问题,然而缓存虽好用,但也并非万能,某些场景依然无法覆盖.比如:需要实时.多次调用第三方AP ...

随机推荐

  1. deepin可视化程序打不开问题排查方法

    anyconnect是一个VPN软件,在deepin系统下安装完成之后,并不能够直接使用,点击启动图标之后没有反应. 要想分析问题,必须从命令行入手,错误会打印在控制台. 如何根据一个图标来找到一个程 ...

  2. npm 查看全局安装模块

    方法一: npm list -g --depth 0 方法二: 输入npm root -g  得到全局node_modules的地址 在任意文件夹输入此地址,便可查看所安模块 https://blog ...

  3. python 树与二叉树的实现

    1.树的基本概念 1.树的定义 树的定义是递归的,树是一种递归的数据结构. 1)树的根结点没有前驱结点,除根结点之外所有结点有且只有一个前驱结点 2)树中所有结点可以有零个或多个后继结点 2.树的术语 ...

  4. undefined reference to `BN_new'

    出现如下错误 undefined reference to `BN_CTX_new' undefined reference to `BN_new' undefined reference to `B ...

  5. vue学习指南:第九篇(详细) - Vue的 Slot-插槽

    Slot  v-slot 插槽元素 浏览器在解析时候首先把它当作标签来解析,只有遇到不认识的就不管了,直接跳过,当你发现是组件,在以组件形式解析. 使用插槽的好处? 比如一个网站 分布顶部都是一样的, ...

  6. LeetCode——Rank Scores

    Write a SQL query to rank scores. If there is a tie between two scores, both should have the same ra ...

  7. yum 安装apache php mysql

    安装: yum install -y httpd php 查看版本:. rpm -qa httpd php httpd-2.2.15-54.el6.centos.x86_64 php-5.3.3-48 ...

  8. mysql-5..6.23-win64.zip安装及配置

    MySQL是一个小巧玲珑但功能强大的数据库,目前十分流行.但是官网给出的安装包有两种格式,一个是msi格式,一个是zip格式的.很多人下了zip格式的解压发现没有setup.exe,面对一堆文件一头雾 ...

  9. 《Linux就该这么学》课堂笔记01 linux初识

    此书作者刘遄(Liu Chuán)从事于Linux运维技术行业,并且在2012年获得红帽工程师RHCE 6版本证书,在2015年初又分别获得红帽工程师RHCE 7版本证书与红帽架构师认证RHCA顶级证 ...

  10. 安装系统时出现 Windows无法打开所需的文件 C:\Sources\install.wim 的解决办法

    使用U盘安装Win10的时候,出现 Windows无法打开所需的文件 C:\Sources\install.wim,错误代码:0x8007000D,这是由于启动盘里 install.wim 文件不正确 ...