全局变量在烧瓶中是否安全? [英] Are global variables thread safe in flask?

查看:175
本文介绍了全局变量在烧瓶中是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 在我的应用程序中,通用对象的状态是通过发出请求来更改的,响应取决于状态。 class SomeObj():
def __init __(self,param):
self.param = param
def query(self):
self.param + = 1
返回self.param

global_obj = SomeObj(0)

@ app.route('/')
def home():
flash( global_obj.query())
render_template('index.html')

这在我的开发服务器上,我期望得到1,2,3等。如果请求是从100个不同的客户端同时进行,是否会出现问题?预期的结果是100个不同的客户端都会看到1到100之间的唯一数字。或者会发生类似的情况:


  1. 客户端1查询。 self.param 加1。

  2. 在执行return语句之前,线程切换到客户端2. self.param 会再次递增。

  3. 线程切换回客户端1,客户端返回数字2。 li>
  4. 现在线程移动到客户端2并返回他/她的数字3。

因为那里只有两个客户,预期的结果是1和2,而不是2和3.一个数字被跳过。

当我扩大我的应用程序时,这实际上会发生吗?我应该看一下全球变量的其他选择吗?

解决方案

您不能使用全局变量来保存这类数据。它不仅不是线程安全的,而且也不是安全的,生产中的WSGI服务器产生了多个进程。所以,如果你使用线程来处理请求,那么你的计数不会是错误的,它们也会根据处理请求的进程而有所不同。



开发服务器是单线程,默认单进程。你不会看到你描述的行为,因为每个请求将被同步处理。启用线程或进程,你会看到它。 app.run(threaded = True) app.run(processes = 10)



使用Flask外部的数据源来保存全局数据。数据库,memcached或redis都是合适的独立存储区域,具体取决于您的需要。您也可以使用会话获取每个用户的简单数据。


In my app the state of a common object is changed by making requests, and the response depends on the state.

class SomeObj():
    def __init__(self, param):
        self.param = param
    def query(self):
        self.param += 1
        return self.param

global_obj = SomeObj(0)

@app.route('/')
def home():
    flash(global_obj.query())
    render_template('index.html')

If I run this on my development server, I expect to get 1, 2, 3 and so on. If requests are made from 100 different clients simultaneously, can something go wrong? The expected result would be that the 100 different clients each see a unique number from 1 to 100. Or will something like this happen:

  1. Client 1 queries. self.param is incremented by 1.
  2. Before the return statement can be executed, the thread switches over to client 2. self.param is incremented again.
  3. The thread switches back to client 1, and the client is returned the number 2, say.
  4. Now the thread moves to client 2 and returns him/her the number 3.

Since there were only two clients, the expected results were 1 and 2, not 2 and 3. A number was skipped.

Will this actually happen as I scale up my application? What alternatives to a global variable should I look at?

解决方案

You can't use global variables to hold this sort of data. Not only is it not thread safe, it's not process safe, and WSGI servers in production spawn multiple processes. So not only would your counts be wrong if you were using threads to handle requests, they would also vary depending on which process handled the request.

The development server is single thread, single process by default. You won't see the behavior you describe since each request will be handled synchronously. Enable threads or processes and you will see it. app.run(threaded=True) or app.run(processes=10).

Use a data source outside of Flask to hold global data. A database, memcached, or redis are all appropriate separate storage areas, depending on your needs. You could also use the session for simple data that is per-user.

这篇关于全局变量在烧瓶中是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆