当reloader = True时,Python计时器函数使用bottle.py运行两次

时间:2016-05-14 18:08:52

标签: python multithreading bottle

虽然我遇到了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...

有关如何使用重新加载器,但防止计时器问题的任何想法?

1 个答案:

答案 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