Работая с глобальным синглтоном во Flask (WSGI), нужно ли мне беспокоиться о состоянии гонки?
Привет мир демо для Flask это:
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 ответа
Вы можете использовать замок:
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()
Вы можете попробовать локальный класс из werkzeug. Вот некоторая информация об этом: Местные жители контекста
Пример:
from flask import Flask
from werkzeug.local import Local
app = Flask(__name__)
loc = Local()
loc.a = 1
loc.b = 2
loc.c = 3
@app.route("/")
def hello():
loc.a += 1
loc.b += loc.a
loc.c += loc.b
return "Hello World!"
if __name__ == "__main__":
app.run()
Вы могли бы взглянуть на g
Объект, который вы можете импортировать непосредственно из колбы, сохраняет объект глобально для этого запроса. Если вы используете управляемый событиями WSGI-сервер (торнадо, gevent и т. Д.), У вас не должно возникнуть никаких проблем.