14

假设我有一个看起来像这样的长时间运行的 python 函数?

import random
import time
from rx import Observable
def intns(x):
    y = random.randint(5,10)
    print(y)
    print('begin')
    time.sleep(y)
    print('end')
    return x

我希望能够设置超时1000ms

所以我在做类似的事情,创建一个 observable 并通过上述密集计算对其进行映射。

a = Observable.repeat(1).map(lambda x: intns(x))

现在对于每个发出的值,如果它需要超过 1000 毫秒,我想结束可观察的,一旦我达到1000ms使用on_erroron_completed

a.timeout(1000).subscribe(lambda x: print(x), lambda x: print(x))

上面的语句确实超时,并调用on_error,但它继续完成计算强度计算,然后才返回到下一条语句。有没有更好的方法来做到这一点?

最后一条语句打印以下内容

8 # no of seconds to sleep
begin # begins sleeping, trying to emit the first value
Timeout # operation times out, and calls on_error
end # thread waits till the function ends

这个想法是,如果一个特定的函数超时,我希望能够继续我的程序,并忽略结果。

我想知道intns函数是否在单独的线程上完成,我猜主线程在超时后继续执行,但我仍然想停止intns线程上的计算函数,或者以某种方式杀死它。

4

5 回答 5

1

以下是可以使用调用的类with timeout() :

如果代码下的块运行时间超过指定时间,TimeoutError则引发 a。

import signal

class timeout:
    # Default value is 1 second (1000ms)
    def __init__(self, seconds=1, error_message='Timeout'):
        self.seconds = seconds
        self.error_message = error_message
    def handle_timeout(self, signum, frame):
        raise TimeoutError(self.error_message)
    def __enter__(self):
        signal.signal(signal.SIGALRM, self.handle_timeout)
        signal.alarm(self.seconds)
    def __exit__(self, type, value, traceback):
        signal.alarm(0)

# example usage
with timeout() :
    # infinite while loop so timeout is reached
    while True :
        pass

如果我理解您的功能,您的实现如下所示:

def intns(x):
    y = random.randint(5,10)
    print(y)
    print('begin')
    with timeout() :
        time.sleep(y)
    print('end')
    return x
于 2017-12-04T01:26:41.960 回答
0

这样它的工作原理:

import random
import time
import threading
import os

def intns(x):
    y = random.randint(5,10)
    print(y)
    print('begin')
    time.sleep(y)
    print('end')
    return x


thr = threading.Thread(target=intns, args=([10]), kwargs={})
thr.start()
st = time.clock();
while(thr.is_alive() == True):
    if(time.clock() - st > 9):
        os._exit(0)
于 2017-09-07T10:34:09.700 回答
0

您可以使用 time.sleep() 并为 time.clock() 创建一个 while 循环

于 2018-01-18T06:42:17.033 回答
0

您可以使用线程来部分执行此操作尽管在 python 中没有杀死线程的特定方法,但您可以实现一个方法来标记线程结束。

如果线程正在等待其他资源,这将不起作用(在您的情况下,您通过随机等待模拟了“长时间”运行的代码)

另请参阅 是否有任何方法可以杀死 Python 中的线程?

于 2017-09-06T20:39:11.800 回答
0

这是超时的示例

import random
import time
import threading

_timeout = 0

def intns(loops=1):
    print('begin')
    processing = 0
    for i in range(loops):
        y = random.randint(5,10)
        time.sleep(y)
        if _timeout == 1:
            print('timedout end')
            return
        print('keep processing')
    return

# this will timeout
timeout_seconds = 10
loops = 10

# this will complete
#timeout_seconds = 30.0
#loops = 1

thr = threading.Thread(target=intns, args=([loops]), kwargs={})
thr.start()
st = time.clock();
while(thr.is_alive() == True):
    if(time.clock() - st > timeout_seconds):
        _timeout = 1

thr.join()
if _timeout == 0:
    print ("completed")
else:
    print ("timed-out")
于 2017-09-08T15:29:08.780 回答