Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python异步线程异常处理_Python_Multithreading_Exception_Asynchronous_Ctypes - Fatal编程技术网

python异步线程异常处理

python异步线程异常处理,python,multithreading,exception,asynchronous,ctypes,Python,Multithreading,Exception,Asynchronous,Ctypes,我试图在Python中实现超时功能 它的工作原理是使用函数装饰器包装函数,该装饰器将函数作为线程调用,但也会调用“看门狗”线程,该线程将在指定的时间段过后在函数线程中引发异常 它目前适用于不睡眠的线程。在do\u rand调用期间,我怀疑在time.sleep调用之后以及在执行超出try/except块之后,实际上调用了“异步”异常,因为这将解释由错误启动的线程中的未处理异常。此外,do\u rand调用的错误在调用7秒后生成(持续时间为time.sleep) 我如何“唤醒”一个线程(使用cty

我试图在Python中实现超时功能

它的工作原理是使用函数装饰器包装函数,该装饰器将函数作为线程调用,但也会调用“看门狗”线程,该线程将在指定的时间段过后在函数线程中引发异常

它目前适用于不睡眠的线程。在
do\u rand
调用期间,我怀疑在
time.sleep
调用之后以及在执行超出
try/except
块之后,实际上调用了“异步”异常,因为这将解释由
错误启动的线程中的
未处理异常。此外,
do\u rand
调用的错误在调用7秒后生成(持续时间为
time.sleep

我如何“唤醒”一个线程(使用ctypes?),让它响应异步异常

或者可能是完全不同的方法

代码:


您需要使用睡眠以外的其他方法,或者您需要向另一个线程发送信号以使其醒来


我使用的一个选项是设置一对文件描述符,并使用select或poll而不是sleep,这允许您向文件描述符写入一些内容以唤醒另一个线程。或者,如果您只需要等待睡眠结束,操作就会出错,因为它花费的时间太长,其他一切都不取决于它。

问题在于时间。睡眠会阻塞。它很难阻止,所以唯一能真正打断它的就是处理信号。但是带有它的代码变得非常混乱,在某些情况下甚至信号都不起作用(例如,当您正在执行阻塞
socket.recv()
,请参见以下内容:)

因此,通常中断线程(而不终止整个进程)是不可能的(更不用说有人可以简单地从线程重写您的信号处理)

但是在这种特殊情况下,您可以使用线程模块中的
事件
类,而不是使用
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
实例)

请注意,
state
将是事件的内部状态。因此,
state==True
将意味着它已使用
.set()
解锁,而
state==False
将意味着发生超时

在此处阅读有关活动的更多信息:


我如何向线程发送信号?哪个信号?
信号
模块将执行此操作。不过,文件描述符方法可能更可靠。我非常希望避免使用文件。所以信号没有任何特别之处,比如,任何will都可以吗?我会避免使用SIGTERM和SIGKILL您可能需要添加一个信号处理程序,以避免信号终止进程。你正依赖于信号传输,这也会中断你所期望的线程的睡眠。这可能不适用于所有操作系统。您的问题是睡眠会停止线程的运行,因此它在退出睡眠之前不会看到引发异常的请求。如果你想要一个可中断的睡眠,你需要使用我提到的选择/轮询机制,或者你可以考虑使用一个条件变量或类似的工具。请参阅
线程化
模块。感谢您的回复,但是,本代码的重点是库(希望如此)。因此,我真的不想限制用户代码以排除time.sleep或任何其他阻塞函数的使用
do_rand
只是一个测试。我希望我可以使用ctypes(或类似的)修改PyThreadState:@dilbert,正如我所说的:
recv()
之类的系统调用可能(并且在阻塞
recv()
的情况下也会)无限期地锁定线程。如果不(强制)终止整个过程,您将无法中断它。因此,我认为你会走得更远,这个问题无法解决。但你应该问的问题是:这首先是个问题吗?也许允许阻塞整个线程一点也不坏?在Windows上,只有主线程可以从
时间中断。sleep
。它在事件上使用
WaitForSingleObject
,而所有其他线程使用不间断
Sleep
。在POSIX系统上,
time.sleep
使用的
select
调用可以使用
pthread\u kill
中断,以线程为目标。@freakish,这是一个公平的观点。这段代码的思想是终止长时间运行的任务,这些任务违反了开发人员对执行时间的预期。@eryksun,一方面,感谢您提供的信息,但另一方面,这非常令人不安(关于Windows非主线程)。
from threading import Event

ev = Event()
ev.clear()

state = ev.wait(rand_pause) # this blocks until timeout or .set() call
ev.set() # this will unlock .wait above