首页 / PYTHON / python异步线程异常处理
python异步线程异常处理
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python异步线程异常处理,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3341字,纯文字阅读大概需要5分钟。
内容图文
![python异步线程异常处理](/upload/InfoBanner/zyjiaocheng/659/bc0ac0bef21f44968ceae6fb3feb962e.jpg)
我正在尝试在Python中实现超时功能.
它通过使用函数装饰器包装函数来工作,该函数装饰器将函数作为线程调用,还调用“看门狗”线程,该线程将在指定时间段后在函数线程中引发异常.
当前,它适用于不休眠的线程.在do_rand调用期间,我怀疑在time.sleep调用之后以及执行已超出try / except块之后,实际上正在调用“异步”异常,因为这将解释错误启动的线程中的Unhandled异常.此外,do_rand调用中的错误是在调用后7秒钟(time.sleep的持续时间)生成的.
我将如何“唤醒”线程(使用ctypes?)以使其响应异步异常?
或者可能是完全不同的方法?
码:
# Import System libraries
import ctypes
import random
import sys
import threading
import time
class TimeoutException(Exception):
pass
def terminate_thread(thread, exc_type = SystemExit):
"""Terminates a python thread from another thread.
:param thread: a threading.Thread instance
"""
if not thread.isAlive():
return
exc = ctypes.py_object(exc_type)
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(thread.ident), exc)
if res == 0:
raise ValueError("nonexistent thread id")
elif res > 1:
# """if it returns a number greater than one, you're in trouble,
# and you should call it again with exc=NULL to revert the effect"""
ctypes.pythonapi.PyThreadState_SetAsyncExc(thread.ident, None)
raise SystemError("PyThreadState_SetAsyncExc failed")
class timeout_thread(threading.Thread):
def __init__(self, interval, target_thread):
super(timeout_thread, self).__init__()
self.interval = interval
self.target_thread = target_thread
self.done_event = threading.Event()
self.done_event.clear()
def run(self):
timeout = not self.done_event.wait(self.interval)
if timeout:
terminate_thread(self.target_thread, TimeoutException)
class timeout_wrapper(object):
def __init__(self, interval = 300):
self.interval = interval
def __call__(self, f):
def wrap_func(*args, **kwargs):
thread = threading.Thread(target = f, args = args, kwargs = kwargs)
thread.setDaemon(True)
timeout_ticker = timeout_thread(self.interval, thread)
timeout_ticker.setDaemon(True)
timeout_ticker.start()
thread.start()
thread.join()
timeout_ticker.done_event.set()
return wrap_func
@timeout_wrapper(2)
def print_guvnah():
try:
while True:
print "guvnah"
except TimeoutException:
print "blimey"
def print_hello():
try:
while True:
print "hello"
except TimeoutException:
print "Whoops, looks like I timed out"
def do_rand(*args):
try:
rand_num = 7 #random.randint(0, 10)
rand_pause = 7 #random.randint(0, 5)
print "Got rand: %d" % rand_num
print "Waiting for %d seconds" % rand_pause
time.sleep(rand_pause)
except TimeoutException:
print "Waited too long"
print_guvnah()
timeout_wrapper(3)(print_hello)()
timeout_wrapper(2)(do_rand)()
解决方法:
问题是time.sleep阻塞了.而且它真的很难阻挡,因此唯一可以中断它的是过程信号.但是带有它的代码真的很混乱,在某些情况下甚至信号也无法正常工作(例如,当您正在阻塞socket.recv()时,请参见:recv() is not interrupted by a signal in multithreaded environment).
因此,通常无法中断线程(而不杀死整个进程)(更不用说有人可以简单地从线程中重写信号处理).
但是在这种特殊情况下,您可以使用线程模块中的Event类来代替使用time.sleep:
线程1
from threading import Event
ev = Event()
ev.clear()
state = ev.wait(rand_pause) # this blocks until timeout or .set() call
线程2(确保它可以访问相同的ev实例)
ev.set() # this will unlock .wait above
请注意,状态将是事件的内部状态.因此,状态== True表示已使用.set()解锁,而状态== False则表示发生了超时.
在此处阅读有关事件的更多信息:
http://docs.python.org/2/library/threading.html#event-objects
内容总结
以上是互联网集市为您收集整理的python异步线程异常处理全部内容,希望文章能够帮你解决python异步线程异常处理所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。