Python ThreadPoolExecutor 异常中止解决方案

Python012

Python ThreadPoolExecutor 异常中止解决方案,第1张

通常情况,我们利用 Ctrl+C 让程序触发 KeyboardInterrupt 异常,中止程序运行。线程池方案下, Ctrl-C 失效,当线程池里的线程任务跑完后,才会触发 KeyboardInterrupt

上下文管理协议相当于隐性地省略了 threadPool.shutdown(wait=True) ,同时,程序正常执行完成或出现异常中断的时候,就会调用 __exit__() 方法,接下来进行异常中止的基础。

适用于 Django 等 WEB 应用框架,本身自带多线程,修改全局变量简单,但要注意线程安全。

程序运行中,只需 sign = 1 或者 exiting.set() ,worker 函数则跳过主要运算部分,剩余线程任务将迅速完成,变相达到中止多线程任务的目的。

提交给线程池的每个线程任务 task 加入 threadPool 中,方便后续对 task 进行操作。当 for 循环内的 task 全部提交后,线程会再后台运行,而进程运行至 while 中堵塞,直至 threadPool 中最后一个线程是否 .done() 。若进程堵塞在 while 中接收到 Ctrl+C KeyboardInterrupt 异常,则从后往前取消 threadPool 中所有任务,达到中止目的。

except (IDontLIkeYouException, YouAreBeingMeanException) as e:pass用逗号分割的方法只能在Python2.6和2.7里好使,在Python3中则无效;

最近因为别的需求,写了一个模块,似乎在这里能用得上:

https://github.com/SakuraSa/ChatProcess

其中的 example.py :

#!/usr/bin/env python

# coding = utf-8

"""

example

"""

__author__ = 'Rnd495'

from time import sleep

from ChatProcess import Chatroom

class Echo(Chatroom):

    """

    Echo

    """

    def response(self, data):

        if data.startswith('sleep'):

            sec = float(data[6:])

            sleep(sec)

            return 'wake up after %dms' % (sec * 1000)

        elif data:

            return data

        else:

            self.stop()

            return 'goodbye'

if __name__ == '__main__':

    from ChatProcess import TimeoutError, ProcessError

    print 'process 01:'

    e = Echo.create_process(lifetime=1).start()

    print e.chat('Hello world!'), e.remain

    print e.chat('sleep:0.1'), e.remain

    print e.chat(''), e.remain

    print ''

    print 'process 02:'

    e = Echo.create_process(lifetime=1).start()

    try:

        print e.chat('Hello world!'), e.remain

        print e.chat('sleep:1.0'), e.remain

        print e.chat(''), e.remain

    except TimeoutError, error:

        print 'error:', error

    print ''

    print 'process 03:'

    e = Echo.create_process(lifetime=1).start()

    try:

        print e.chat('Hello world!'), e.remain

        print e.chat('sleep:not a num'), e.remain

        print e.chat(''), e.remain

    except ProcessError, error:

        print 'error:', error

运行结果为:

process 01:

Hello world! 0.773000001907

wake up after 100ms 0.549000024796

goodbye 0.547000169754

process 02:

Hello world! 0.868000030518

error: TimeoutError

process 03:

Hello world! 0.868000030518

error: ('Error occurred on loop', ValueError('could not convert string to float: not a num',))

在其中的 process01 中,主进程捕获了 超时

在其中的 process02 中,主进程捕获了 子进程的错误

不知道你能不能用得上