我必须在python中执行一个需要执行一段时间的程序然后(无论它在哪里执行)它必须将信息转储到文件,关闭文件然后退出。
此处的行为在JavaScript中与使用setTimeout(func, 1000000)
相同,其中第一个参数(func)将是指向具有退出代码的函数的指针,其第二个参数将是程序执行的可用时间。
我知道如何使用C语言(使用SO信号)制作此程序,但使用python
答案 0 :(得分:51)
在实践中,Timer可能是做你想做的最简单的方法。
此代码将执行以下操作:
===
from threading import Timer
def twoArgs(arg1,arg2):
print arg1
print arg2
print ""
def nArgs(*args):
for each in args:
print each
#arguments:
#how long to wait (in seconds),
#what function to call,
#what gets passed in
r = Timer(1.0, twoArgs, ("arg1","arg2"))
s = Timer(2.0, nArgs, ("OWLS","OWLS","OWLS"))
r.start()
s.start()
===
上述代码很可能会解决您的问题。
但是!有另一种方法,不使用多线程。它更像Javascript,它是单线程的。
对于这个单线程版本,您需要做的就是将函数及其参数存储在对象中,以及运行函数的时间。
一旦你有了包含函数调用和超时的对象,就要定期检查函数是否准备好执行。
执行此操作的正确方法是使priority queue存储我们希望将来运行的所有函数,如下面的代码所示。
就像在Javascript中一样,这种方法无法保证函数能够准确地按时运行。一个需要很长时间才能运行的函数会延迟它之后的函数。但它确实保证函数不会> 而不是超时。
此代码将执行以下操作:
===
from datetime import datetime, timedelta
import heapq
# just holds a function, its arguments, and when we want it to execute.
class TimeoutFunction:
def __init__(self, function, timeout, *args):
self.function = function
self.args = args
self.startTime = datetime.now() + timedelta(0,0,0,timeout)
def execute(self):
self.function(*self.args)
# A "todo" list for all the TimeoutFunctions we want to execute in the future
# They are sorted in the order they should be executed, thanks to heapq
class TodoList:
def __init__(self):
self.todo = []
def addToList(self, tFunction):
heapq.heappush(self.todo, (tFunction.startTime, tFunction))
def executeReadyFunctions(self):
if len(self.todo) > 0:
tFunction = heapq.heappop(self.todo)[1]
while tFunction and datetime.now() > tFunction.startTime:
#execute all the functions that are ready
tFunction.execute()
if len(self.todo) > 0:
tFunction = heapq.heappop(self.todo)[1]
else:
tFunction = None
if tFunction:
#this one's not ready yet, push it back on
heapq.heappush(self.todo, (tFunction.startTime, tFunction))
def singleArgFunction(x):
print str(x)
def multiArgFunction(x, y):
#Demonstration of passing multiple-argument functions
print str(x*y)
# Make some TimeoutFunction objects
# timeout is in milliseconds
a = TimeoutFunction(singleArgFunction, 1000, 20)
b = TimeoutFunction(multiArgFunction, 2000, *(11,12))
c = TimeoutFunction(quit, 3000, None)
todoList = TodoList()
todoList.addToList(a)
todoList.addToList(b)
todoList.addToList(c)
while True:
todoList.executeReadyFunctions()
===
在实践中,你可能会在while循环中继续进行更多操作,而不仅仅是检查你的超时功能是否准备就绪。您可能正在轮询用户输入,控制某些硬件,读取数据等。
答案 1 :(得分:12)
您也可以在python中使用信号(仅限unix)
import signal, sys
# install a SIGALRM handler
def handler(signum, frame):
print "got signal, exiting"
sys.exit(1)
signal.signal(signal.SIGALRM, handler)
# emit SIGALRM after 5 secs
signal.setitimer(signal.ITIMER_REAL, 5)
# do stuff
i = 1
while True:
if i % 100000 == 0:
print i
i += 1
答案 2 :(得分:6)
您可以使用python3的asyncio事件循环的call_later
方法。下面的示例将正常工作。
import asyncio
loop = asyncio.get_event_loop()
def callback():
print("callback")
loop.call_later(1, callback)
loop.call_later(1, callback)
async def main():
while True:
await asyncio.sleep(1)
loop.run_until_complete(main())
答案 3 :(得分:4)
在python 3中使用asyncio
是一个不错的解决方案。
import asyncio
def async_call_later(seconds, callback):
async def schedule():
await asyncio.sleep(seconds)
if asyncio.iscoroutinefunction(callback):
await callback()
else:
callback()
asyncio.ensure_future(schedule())
async def do_something_async():
await asyncio.sleep(0.5)
print('Now! async')
async def main():
print('Scheduling...')
async_call_later(3, do_something_async)
async_call_later(3, lambda: print('Now!'))
print('Waiting...')
await asyncio.sleep(4)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
请注意,python中的sleep和类似功能需要等待数秒钟,因此我已复制了该内容。但是,如果需要毫秒,则可以提供分数。 (例如0.5 => 500ms)。
与asyncio.call_later相比,此方法的优势在于它仅适用于同步回调。如果回调是协程,则此实现awaits
更加健壮。
答案 4 :(得分:-2)
像这样使用Potato:
Salad:
Popcorn:
Cheese
模块:
time