当 reloader=True 时,Python 计时器使用 bottle.py 函数 运行 两次
Python timer functions run twice with bottle.py when reloader=True
虽然 python 计时器有问题,但我发现当 bottle.py 是 运行 和 "reloader = True" 时,所有计时器会快速连续地运行 运行 两次。
我已经用几种不同的调用定时器的方法进行了尝试,结果在所有实例中都是相同的(双触发)。
示例代码:
#!/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...
关于如何使用重新加载器的任何想法,但防止计时器问题?
设置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)
然后 child 每 interval
秒重新启动(默认为 1)。
脚本 top-level 处的任何 运行 都是 运行,无论是在启动 Bottle 服务器时,还是在每次 child 进程再次启动时。
因此,parent 和 child 进程都是独立的 运行ning 计时器。 child 进程中的长定时器永远不会被执行,因为该进程在 5 秒结束之前被终止,但是短定时器可能 只是 在 [=40] 之前设法触发=] 进程终止 child 以再次启动它。
您可以通过测试 BOTTLE_CHILD
环境变量来检测您是否在 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
虽然 python 计时器有问题,但我发现当 bottle.py 是 运行 和 "reloader = True" 时,所有计时器会快速连续地运行 运行 两次。
我已经用几种不同的调用定时器的方法进行了尝试,结果在所有实例中都是相同的(双触发)。
示例代码:
#!/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...
关于如何使用重新加载器的任何想法,但防止计时器问题?
设置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)
然后 child 每 interval
秒重新启动(默认为 1)。
脚本 top-level 处的任何 运行 都是 运行,无论是在启动 Bottle 服务器时,还是在每次 child 进程再次启动时。
因此,parent 和 child 进程都是独立的 运行ning 计时器。 child 进程中的长定时器永远不会被执行,因为该进程在 5 秒结束之前被终止,但是短定时器可能 只是 在 [=40] 之前设法触发=] 进程终止 child 以再次启动它。
您可以通过测试 BOTTLE_CHILD
环境变量来检测您是否在 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