虽然我遇到了python定时器的问题,但我发现当使用" reloader = True"运行bottle.py时,所有定时器函数都会快速连续运行两次。
我尝试了几种不同的调用定时器的方法,结果在所有实例中都是相同的(双击)。
示例代码:
#!/usr/bin/env python
from threading import Timer
from bottle import *
# Short timer
def short_time():
t = Timer(1, short_time)
t.daemon = True
t.start()
print "Short Time..."
# Long timer
def long_time():
t = Timer(5, long_time)
t.daemon = True
t.start()
print "Long Time..."
# The App
app = Bottle()
@app.route('/status')
def default():
return "OK"
#Run the app -----
if __name__ == '__main__':
# Start the short timer.
short_time()
# Start the long timer.
long_time()
# Run the app
# This interferes with the timers
run(app, host='0.0.0.0', port=8002, reloader=True)
#This one works as expected
#run(app, host='0.0.0.0', port=8002) #This works fine
启用了重新加载器的输出:
Short Time...
Short Time...
Short Time...
Short Time...
Short Time...
Short Time...
Short Time...
Short Time...
Long Time...
Short Time...
Long Time...
Short Time...
Short Time...
Short Time...
预期输出(没有重新加载器):
Short Time...
Short Time...
Short Time...
Short Time...
Long Time...
Short Time...
Short Time...
Short Time...
Short Time...
Short Time...
Long Time...
Short Time...
Short Time...
有关如何使用重新加载器,但防止计时器问题的任何想法?
答案 0 :(得分:3)
设置reloader=True
后,瓶子流程re-runs the script as a child process:
if reloader and not os.environ.get('BOTTLE_CHILD'): import subprocess lockfile = None try: fd, lockfile = tempfile.mkstemp(prefix='bottle.', suffix='.lock') os.close(fd) # We only need this file to exist. We never write to it while os.path.exists(lockfile): args = [sys.executable] + sys.argv environ = os.environ.copy() environ['BOTTLE_CHILD'] = 'true' environ['BOTTLE_LOCKFILE'] = lockfile p = subprocess.Popen(args, env=environ)
然后每隔interval
秒(默认为1)重新启动 。
在启动瓶子服务器时以及每次再次启动子进程时,都会运行在脚本顶级运行的任何内容。
因此,父和子进程都是独立运行的计时器。子进程中的长计时器永远不会被执行,因为该进程在5秒启动之前被终止,但是短计时器可能只是设法在父进程杀死子进程再次启动之前触发。
您可以通过测试BOTTLE_CHILD
环境变量来检测您是否在子进程中:
import os
if os.environ.get('BOTTLE_CHILD'):
# in the child process, do something special perhaps?
# this will be executed *each time the child is restarted*
else:
# in the parent process, which restarts the child process