2012-04-16 33 views
13

Flask için merhaba dünya demo: Ben şöyle bu değiştirilmiş neFlask'ta (WSGI) küresel bir singleton ile çalışmak, yarış koşulları hakkında endişelenmek zorunda mıyım?

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

Birden konuları sahip olabilir WSGI uygulama anlıyoruz. hello işlevi, aynı anda birden fazla iş parçacığı üzerinde çalışıyor olabilir ve sonra bir yarış durumumuz olur. Bu doğru mu? Yukarıdaki kod iş parçacığı güvenli değilse, iş parçacığı güvenli hale getirmek için ne yapabilirim?

Globals'tan kaçınmak olası bir çözümdür, ancak her zaman globals'tan kaçınabilir misiniz? Ya bir python nesne önbelleği gibi bir şey istiyorsam?

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

cevap

6

Bir kilidi kullanabilirsiniz. Etkin bir WSGI sunucusu (tornado, gevent, vb.) Kullanıyorsanız, herhangi bir sorunla karşılaşmamalısınız.

+3

Kişisel örneği (kesilmiş ve tam olarak yapıştırılan) bir göreve kadar başvurulduğu için, benim için bir 500 döndürür. – jeremyjjbrown

+0

Bu aslında belirtilen soruya cevap vermiyor. Kilitlenecek _need_? Hangi koşullar altında? Bu sadece GIL olmayan tercümanlar için mi? – Basic

0

Sen, şişenin içe aktarım yapabilir g nesneye bakmak bu istek için küresel bir nesneyi tutar olabilir:

+4

"g" nesnesinin yalnızca bir istek sırasında durumu koruduğunu ve bu nedenle yukarıdaki kullanım için yararlı olmadığını düşündüm. – osa

2

Yerel sınıfı werkzeug'den deneyebilirsiniz. İşte bu konuda bazı bilgiler verilmiştir: Context Locals

Örnek:

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