当 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