代码之家  ›  专栏  ›  技术社区  ›  user3091850

Python定时器函数对瓶子运行两次。重新加载时的py=真

  •  2
  • user3091850  · 技术社区  · 10 年前

    当我遇到python定时器的问题时,我发现瓶子。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...
    

    关于如何使用重载,但要防止计时器问题,有什么想法吗?

    1 回复  |  直到 9 年前
        1
  •  3
  •   Community Mohan Dere    9 年前

    什么时候 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