python全局变量global线程安全,全局变量在flask中是线程安全的吗?如何在请求之间共享数据?...

本文讨论了在Flask应用中,使用全局变量存储对象状态的潜在问题。当同时处理大量请求时,不适当的全局变量可能导致计数错误和数据跳变。建议使用数据库、缓存或进程间的数据共享机制来解决,如数据库存储、Memcached或Redis。还提到了Flask的gobject作为请求级全局数据的选项,以及区分那些仅在每个请求期间存在的‘伪全局’资源管理对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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:

Client 1 queries. self.param is incremented by 1.

Before the return statement can be executed, the thread switches over to client 2. self.param is incremented again.

The thread switches back to client 1, and the client is returned the number 2, say.

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. 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.

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. If you need to load and access Python data, consider multiprocessing.Manager. You could also use the session for simple data that is per-user.

The development server may run in single thread and process. 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). (In 1.0 the server is threaded by default.)

Some WSGI servers may support gevent or another async worker. Global variables are still not thread safe because there's still no protection against most race conditions. You can still have a scenario where one worker gets a value, yields, another modifies it, yields, then the first worker also modifies it.

If you need to store some global data during a request, you may use Flask's g object. Another common case is some top-level object that manages database connections. The distinction for this type of "global" is that it's unique to each request, not used between requests, and there's something managing the set up and teardown of the resource.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值