【Python ThreadPoolExecutor 强制结束多线程】

强制结束多线程

多线程并发执行可以极大地缩减代码运行时间,但有些时候我们想要程序可以在不满足限制条件时,正常并发执行;在满足限制条件后,强制结束多线程,不让其再空耗资源。
举几个例子:我们想要程序可以并发执行操作,但只并发执行50个操作就好了,之后即使还有其他操作也不再执行;或者我们想要得到几千个并发操作中返回值的最大值,但已知返回值取值范围为0到100,所以当我们发现已有返回值为100时,其他所有正在执行的程序和未执行的等待程序都没有了意义,可以强制结束多线程任务,以免空耗资源。

方案一(满足条件即可强制结束多线程但无法处理返回值)

代码思路如下:

from concurrent.futures import as_completed, ProcessPoolExecutor, wait, ALL_COMPLETED, FIRST_EXCEPTION
from concurrent.futures.thread import ThreadPoolExecutor
import random
import threading
import time
import queue
import concurrent


def rand_sleep(i,exec_queue):
    if not exec_queue.empty():
        return -1
    try:
        if i == 5:
            print("先返回的数据已经满足条件 则 剩下的线程结果 不再处理。。。")
            raise Exception("The number is 5.")
        time.sleep(i)
        print(i)
        return i

    except Exception as e:
        print(e)
        exec_queue.put("Termination")
        raise Exception(e)


if __name__ == "__main__":
    exec_queue = queue.Queue()
    ex = ThreadPoolExecutor(3)
    tasks = [ ex.submit(rand_sleep, i,exec_queue) for i in range(30)]

    wait(tasks, return_when=FIRST_EXCEPTION)
    # 反向序列化之前塞入的任务队列,并逐个取消
    for task in reversed(tasks):
        task.cancel()
    # 等待正在执行任务执行完成
    wait(tasks, return_when=ALL_COMPLETED)

    # max_value = 0
    # for future in as_completed(tasks):
    #     if max_value < future.result():
    #         max_value = future.result()

    print("继续处理下面程序")
    # print(max_value)
    for j in range(90,100):
        time.sleep(j-89)
        print(j)

只需在并发函数中多传一个参数,作为标记,当程序执行到第5个时,并发函数内的代码会直接返回一个报错,之后并发函数会再返回一个报错给主函数,主函数得到报错,将正在执行任务逐个取消,主函数代码继续执行下去。但可惜的是,这样主函数既会收到并发函数的返回值,也会收到报错,因此无法得到并行操作返回值的最大值,也就是说,在这种处理方式下,几乎无法使用as_completed

更好的方案二(既可以结束多线程,也可以处理返回值)

代码思路如下:

def get_ali_fun(times,exec_queue):
    if not exec_queue.empty():
        return -1
    time.sleep(times)
    print(times)
    return times

if __name__ == "__main__":
    exec_queque = queue.Queue()
    executor = ThreadPoolExecutor(2)
    all_task = [executor.submit(get_ali_fun, url,exec_queque) for url in range(20)]

    max_value = 0
    for future in as_completed(all_task):
        try:
            data = future.result()
            if max_value<data:
                max_value =data
            if data == 4:
                print("先返回的数据已经满足条件 则 剩下的线程结果 不再处理。。。")
                raise Exception("The number is 4.")
        except Exception as e:
            print(e)
            exec_queque.put("Termination")
            wait(all_task, return_when=FIRST_EXCEPTION)
            # 反向序列化之前塞入的任务队列,并逐个取消
            for task in reversed(all_task):
                task.cancel()
            # 等待正在执行任务执行完成
            wait(all_task, return_when=ALL_COMPLETED)


    print("继续处理下面程序")
    print(f"最大值为{max_value}")
    for j in range(90,100):
        time.sleep(j-89)
        print(j)

在这种处理方式下,并行函数只返回数值,通过as_completed来处理已执行的函数返回值,这样既可以结束多线程,也可以处理返回值

  • 10
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值