Подтвердить что ты не робот

Работая с глобальным синглом в Flask (WSGI), мне нужно беспокоиться о состоянии гонки?

Демо-версия hello world для 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?

4b9b3361

Ответ 1

Вы можете использовать блокировку:

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()

Ответ 2

Вы можете попробовать локальный класс от 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()

Ответ 3

Вы можете взглянуть на объект g, который вы можете импортировать непосредственно из фляги, сохраняет объект глобально для этого запроса. Если вы используете WSGI-сервер с событиями (торнадо, gevent и т.д.), У вас не должно быть проблем.