在Flask(WSGI)中使用全局单例,我是否必须担心竞争条件?

时间:2012-04-16 21:04:56

标签: python thread-safety wsgi flask race-condition

Flask的hello world演示是:

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

如果我这样修改了怎么办:

from flask import Flask
app = Flask(__name__)

a = 1
b = 2
c = 3

@app.route("/")
def hello():
    a += 1
    b += a
    c += b
    return "Hello World!"

if __name__ == "__main__":
    app.run()

我理解WSGI应用程序可能有多个线程。 hello函数可以同时在多个线程上运行,然后我们就会遇到竞争条件。它是否正确?如果上面的代码不是线程安全的,我该怎么做才能使它的线程安全?

避免全局变量是一种可能的解决方案,但是你总能避免使用全局变量吗?如果我想要类似python对象缓存的东西怎么办?

3 个答案:

答案 0 :(得分:10)

你可以使用锁:

from threading import Lock
from flask import Flask
app = Flask(__name__)

a = 1
b = 2
c = 3
lock = Lock()

@app.route("/")
def hello():
    with lock:
        a += 1
        b += a
        c += b
    return "Hello World!"

if __name__ == "__main__":
    app.run()

答案 1 :(得分:2)

您可以尝试werkzeug的Local类。 以下是有关它的一些信息:Context Locals

示例:

profit({i,j})=max(profit(i),profit(j))+S_ij * min(profit(i),profit(j))

答案 2 :(得分:1)

您可以查看可以直接从flask导入的g对象,为该请求全局保留一个对象。如果您正在使用事件驱动的WSGI服务器(龙卷风,gevent等),那么您应该没有任何问题。