在Windows中一段时间​​后杀死一个函数

时间:2011-05-20 06:42:55

标签: python

我已经阅读了很多关于使用线程,子进程等的帖子。对于我正在尝试做的事情,很多事情似乎过于复杂......

我想做的就是在X时间过后停止执行一个功能。

def big_loop(bob):
    x = bob
    start = time.time()
    while True:
        print time.time()-start

此函数是一个无限循环,永远不会抛出任何错误或异常,句号。 我不确定“命令,shell,子进程,线程等......”和这个函数之间的区别,这就是我在操作子进程时遇到问题的原因。

我在这里找到了这个代码,并试了一下,但是你可以看到它在10秒钟后继续打印:

import time
import threading
import subprocess as sub
import time

class RunCmd(threading.Thread):
    def __init__(self, cmd, timeout):
        threading.Thread.__init__(self)
        self.cmd = cmd
        self.timeout = timeout

    def run(self):
        self.p = sub.Popen(self.cmd)
        self.p.wait()

    def Run(self):
        self.start()
        self.join(self.timeout)

        if self.is_alive():
            self.p.terminate()
            self.join()

def big_loop(bob):
    x = bob
    start = time.time()
    while True:
        print time.time()-start

RunCmd(big_loop('jimijojo'), 10).Run()  #supposed to quit after 10 seconds, but doesn't
x = raw_input('DONEEEEEEEEEEEE')

这个功能被杀死的简单方法是什么。正如你在上面的尝试中所看到的,它不会在20秒后终止并继续......

***哦,我也读过关于使用信号的内容,但是我在Windows上,所以我不能使用闹钟功能..(python 2.7)

**假设“无限运行功能”不能被操纵或改变为非无限,如果我可以改变功能,那么我只是将它改为非无限不是吗?

以下是一些类似的问题,我无法将其代码移植到我的简单函数中: 也许你可以吗?

Python: kill or terminate subprocess when timeout

signal.alarm replacement in Windows [Python]

好的,我尝试了一个收到的答案,但它有效......但是如果我删除if __name__ == "__main__":声明怎么能用呢?当我删除这个语句时,循环永远不会像之前那样结束..

import multiprocessing
import Queue
import time


def infinite_loop_function(bob):
    var = bob
    start = time.time()
    while True:
        time.sleep(1)
        print time.time()-start
    print 'this statement will never print'

def wrapper(queue, bob):
    result = infinite_loop_function(bob)
    queue.put(result)
    queue.close()



#if __name__ == "__main__":

queue = multiprocessing.Queue(1) # Maximum size is 1
proc = multiprocessing.Process(target=wrapper, args=(queue, 'var'))
proc.start()

# Wait for TIMEOUT seconds
try:
    timeout = 10
    result = queue.get(True, timeout)
except Queue.Empty:
    # Deal with lack of data somehow
    result = None
finally:
    proc.terminate()

print 'running other code, now that that infinite loop has been defeated!'
print 'bla bla bla'
x = raw_input('done')

4 个答案:

答案 0 :(得分:6)

使用multiprocessing模块中的构建基块:

import multiprocessing
import Queue

TIMEOUT = 5

def big_loop(bob):
    import time
    time.sleep(4)
    return bob*2

def wrapper(queue, bob):
    result = big_loop(bob)
    queue.put(result)
    queue.close()

def run_loop_with_timeout():
    bob = 21 # Whatever sensible value you need
    queue = multiprocessing.Queue(1) # Maximum size is 1
    proc = multiprocessing.Process(target=wrapper, args=(queue, bob))
    proc.start()

    # Wait for TIMEOUT seconds
    try:
        result = queue.get(True, TIMEOUT)
    except Queue.Empty:
        # Deal with lack of data somehow
        result = None
    finally:
        proc.terminate()

    # Process data here, not in try block above, otherwise your process keeps running
    print result

if __name__ == "__main__":
    run_loop_with_timeout()

您也可以使用Pipe / Connection对完成此操作,但我不熟悉他们的API。更改睡眠时间或TIMEOUT以检查两种情况的行为。

答案 1 :(得分:0)

如果没有在单独的进程中运行该函数,则在一定时间后杀死函数没有直接的方法。一种更好的方法可能是重写函数,使其在指定的时间后返回:

import time

def big_loop(bob, timeout):
    x = bob
    start = time.time()
    end = start + timeout
    while time.time() < end:
        print time.time() - start
        # Do more stuff here as needed

答案 2 :(得分:0)

import os,signal,time
cpid = os.fork()
if cpid == 0:
  while True:
     # do stuff
else:
  time.sleep(10)
  os.kill(cpid, signal.SIGKILL)

你也可以检查一个线程的循环,这个事件更加便携和灵活,因为它允许其他反应而不是暴力杀戮。但是,如果# do stuff需要花费时间(甚至在某些事件上永远等待),此方法将失败。

答案 3 :(得分:0)

你不能从循环中返回吗?

start = time.time()
endt = start + 30
while True:
    now = time.time()
    if now > endt:
        return
    else:
        print end - start