通常情况,我们利用 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 中,主进程捕获了 子进程的错误
不知道你能不能用得上