【问题标题】:How to timeout a statement如何使语句超时
【发布时间】:2014-05-08 12:22:55
【问题描述】:

如何在 python 中使语句/代码块超时?

我尝试使用下面的帖子查看帖子,但无法识别信号:

wls:/offline> import signal

Traceback (innermost last):

  File "<console>", line 1, in ?

ImportError: no module named signal

代码:

import os
import signal

def handler(signum, frame):
    print "Forever is over!"    
    raise Exception("end of time")

def loop_forever():
    import time
    while 1:
        print "sec"
        time.sleep(1)

signal.signal(signal.SIGALRM, handler)
signal.alarm(10)

try:
    loop_forever()
except Exception, exc:
    print exc

【问题讨论】:

  • 用线程不是更容易做到吗?
  • 你在什么操作系统上运行它?以上应该适用于基于UNIX 的系统
  • @RiccardoCagnasso 不一定,线程并不总是 python 中的最佳选择。而且这个 sn-p 对我来说很容易完成 ;-)
  • 我观察到的一件事是,如果我将它作为 python 脚本运行它可以工作。如果我使用 java/WLST 运行它,它不会识别信号

标签: python python-2.7 jython wlst


【解决方案1】:

您的代码对我来说运行良好:

>>> import os
>>> import signal
>>> 
>>> def handler(signum, frame):
...     print "Forever is over!"    
...     raise Exception("end of time")
... 
>>> def loop_forever():
...     import time
...     while 1:
...         print "sec"
...         time.sleep(1)
... 
>>> signal.signal(signal.SIGALRM, handler)
0
>>> signal.alarm(10)
0
>>> 
>>> try:
...     loop_forever()
... except Exception, exc:
...     print exc
... 
sec
sec
sec
sec
sec
sec
sec
sec
sec
sec
Forever is over!
end of time

但是,您是否使用 Unix 系统来尝试这个?这是 Linux、BSD 还是 Mac?信号模块可能根本不存在于其他操作系统上,因为它使用了一个非常特定于 unix 系统的功能,尽管 windows 确实对 POSIX 进程有非常基本的支持。

edit:好吧,正如我所说,您处于一个非常特殊的情况下,既不是 Unix 也不是 windows 甚至 symbian ;但是您在 Jython 中运行它,它无法访问操作系统功能,而缺少 signal 模块。您应该使用 Jython 标记您的问题,以帮助我们更有效地帮助您!那么你最好使用一个线程定时器,它应该在 Jython 中很好地实现。

作为一个非常基本的例子:

 >>> threading.Timer(5.0, lambda: print("toto")).start()

作为一个更复杂的例子,我使用一个简单的锁信号量来处理 主线程和定时器线程之间的信令:

>>> import time
>>> import threading
>>> l = threading.Lock()
>>> threading.Timer(5.0, lambda l: l.acquire(), args=(l,)).start()
>>> while not l.locked():
...   print("sec")
...   time.sleep(1)
... 
sec
sec
sec
sec
sec
>>> 

【讨论】:

  • signal 作为 Windows 上可用的模块,它仅限于可能信号的一个非常小的子集。该文档指定了平台上可用的内容
  • 这就是我使用模态 may 并添加“即使 windows 确实对 POSIX 进程有非常基本的支持”的原因。 ;-)
  • 我观察到的一件事是,如果我将它作为 python 脚本运行它可以工作。如果我使用 java/WLST 运行它,它不会识别信号
  • 好吧,正如我所说,您处于一个非常特殊的情况,既不是 Unix 也不是 Windows,但是您在 Jython 中运行它,它无法访问操作系统功能,而缺少signal 模块。那么你最好使用一个线程计时器,它应该在 Jython 中很好地实现。
  • @zmo 确实,这就是我的观点。 signal 应该在 Windows 上可用,所以它不会解释 ImportError。但是如果 Jython 不能传递信号,因此没有实现 signal 模块,那会。
【解决方案2】:

这似乎有效

超时后调用方法:

from threading import Timer

import time


def timeout():

    print 'in timeout'


def main():

    print 'it keeps going and going ',

    while 1:

        print 'and going '

        time.sleep(3)


try:

    Timer(5.0,timeout).start()

    main()

except:

    print "whoops"

【讨论】:

    猜你喜欢
    • 2015-12-24
    • 2019-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    • 2011-12-17
    • 1970-01-01
    • 2011-09-23
    相关资源
    最近更新 更多