【问题标题】:Python Flask update var after new request新请求后Python Flask更新var
【发布时间】:2020-04-09 15:03:25
【问题描述】:

我在 Python 中创建了一个简单的脚本(我是新手)。除了一个小问题,一切都按需要运行。

我的项目: 我通过 http 向我的服务器发送请求: {ip-of-server}/?speed=999&time=8&cents=50

这将在您的 shell 中显示一个倒数计时器。在这种情况下从 8 倒数到 0。效果很好。当我发送 {ip-of-server}/?speed=499&time=8&cents=50 时,它会以两倍的速度倒计时。这是根据需要。

我面临的问题: 在倒计时期间,我需要能够向我的服务器发送新请求。它应该使用新值更新倒计时。目前它将创建 2 个倒计时。如果您阅读脚本,这是正确的,但不是我需要的。我需要一些帮助来更新现有的倒计时。

我的代码:

from flask import Flask, request
app = Flask(__name__)
import time

@app.route('/', methods = ["GET"])

def post():
    speed = float(request.args["speed"])
    thetime = request.args["time"]
    cents = request.args["cents"]

    print('\n')
    print('AccuView Digital:')
    print('Speed:', speed,' Time:', thetime,' Cents:', cents)
    print('-------------------------------')

    def countdown(thetime):
        while thetime:
            mins, secs = divmod(thetime, 60)
            timer = '{:02d}:{:02d}'.format(mins, secs)
            print('Tijd:', timer, end="\r")
            time.sleep((speed+1)/1000)
            thetime -= 1
            if thetime == 0:
                print('Werp geld in\n') 
    countdown(int(thetime))
    return '1'

app.run(host='192.168.1.107', port= 8090)

谢谢

【问题讨论】:

    标签: python flask python-requests countdown


    【解决方案1】:

    正如您自己所说,脚本运行良好。所以现在发生的事情是烧瓶正在创建线程来满足您的请求。您发送第一个请求,flask 在一个线程上启动一个计数器,当您发送另一个请求时,flask 启动另一个线程,另一个计数器在该线程上运行。两个线程都有自己的值speedthetimecents,一个线程不能更改另一个线程中变量的值。

    所以我们要做的是从任何线程访问/修改变量的值。一种简单的解决方案是使用全局变量,以便所有线程都可以访问这些变量。

    解决方案:

    1. speedthetimecents 设为全局变量,以便可以从任何线程修改它们。
    2. 当我们收到请求时,检查计数器是否已经在运行(我们可以通过检查全局变量 thetime 的值是否为 0 来做到这一点。
    3. 我们知道现有计数器是否正在运行,现在只需更新全局变量的值。
    4. 如果没有现有的计数器在运行,则启动计数器(调用方法countdown())。否则我们不需要做任何事情(我们已经在上一步更新了全局变量的值,所以现有的计数器也会更新)。

    代码:

    import time
    from flask import Flask, request
    
    app = Flask(__name__)
    
    # We create global variables to keep track of the counter
    speed = thetime = cents = 0
    
    
    @app.route('/', methods=["GET"])
    def post():
        global speed, thetime, cents
    
        # Check if previous counter is running
        counter_running = True if thetime else False
    
        thetime = int(request.args["time"])
        speed = float(request.args["speed"])
        cents = request.args["cents"]
    
        print('\n')
        print('AccuView Digital:')
        print('Speed:', speed, ' Time:', thetime, ' Cents:', cents)
        print('-------------------------------')
    
        def countdown():
            global thetime, speed
            while thetime:
                mins, secs = divmod(thetime, 60)
                timer = '{:02d}:{:02d}'.format(mins, secs)
                print('Tijd:', timer, end="\r")
                time.sleep((speed + 1) / 1000)
                thetime -= 1
                if thetime == 0:
                    print('Werp geld in\n')
    
        # If existing counter is running, then we don't start another counter
        if not counter_running:
            countdown()
        return '1'
    
    
    app.run(host='192.168.1.107', port= 8090)
    

    代码(以便我们可以中断睡眠):

    import time
    import threading
    from flask import Flask, request
    
    app = Flask(__name__)
    
    # We create global variables to keep track of the counter
    speed = thetime = cents = 0
    sleep_speed = threading.Event()
    
    
    @app.route('/', methods=["GET"])
    def post():
        global speed, thetime, cents, sleep_speed
    
        # Check if previous counter is running
        counter_running = True if thetime else False
    
        thetime = int(request.args["time"])
        speed = float(request.args["speed"])
        cents = request.args["cents"]
    
        # Make sure to interrupt counter's sleep
        if not sleep_speed.is_set():
            sleep_speed.set()
        sleep_speed.clear()
    
        print('\n')
        print('AccuView Digital:')
        print('Speed:', speed, ' Time:', thetime, ' Cents:', cents)
        print('-------------------------------')
    
        def countdown():
            global thetime, speed
            while thetime:
                mins, secs = divmod(thetime, 60)
                timer = '{:02d}:{:02d}'.format(mins, secs)
                print('Tijd:', timer, end="\r")
                sleep_speed.wait((speed + 1) / 1000)
                thetime -= 1
                if thetime == 0:
                    print('Werp geld in\n')
    
        # If existing counter is running, then we don't start another counter
        if not counter_running:
            countdown()
        return '1'
    
    
    app.run(host='0.0.0.0', port=8090)
    

    【讨论】:

    • 这很好用。我唯一的问题是当我发送 6000000 作为速度时,它不再起作用了。虽然发送速度 499 和 999 确实如此。发送给我的设备使用速度 6000000 停止计数器,然后发送一个新的请求,时间和速度为 499 或 999。
    • @user3014636 很好,当您发送 speed=6000000 但它进入睡眠状态时它确实有效。所以现在当你发送 sleep=999 时它不起作用,因为线程已经处于睡眠模式并且无法唤醒它。因此,您应该使用Event.wait(),而不是使用time.sleep。用两个代码更新了答案..
    • 工作但有一个问题。在 speed=600000 之后发送的第一个 GET 请求未被捕获(当我使用浏览器发送它时会捕获,但从 iOT 设备接收它时不会捕获)。但是当我删除所有代码并且只为 iOT 创建一个侦听器时看到它进来了,所以首先 speed=6000000 然后我看到 speed=999(或 499)进来,但这没有被捕获。我需要发送两次才能使其正常工作。
    • 有人有想法吗?我被困在这里了。
    • @user3014636 你检查了第二个代码吗? Code (so that we can interrupt sleep):
    猜你喜欢
    • 2021-12-25
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-22
    • 2021-04-12
    • 1970-01-01
    • 2019-04-05
    相关资源
    最近更新 更多