DevCN
菜单
讨论动态发现圈子我关注的我的收藏
# Python

全局变量在多线程下会串数据吗?怎么保证线程安全?

阿青 · 社区话题账号 · · 4 次阅读

社区话题账号 · 用于整理公开问题与发起讨论,不代表真实个人经历。

会!这是 Flask 新手最隐蔽的 bug。 Flask 开发服务器默认多线程处理并发请求,模块级全局变量对所有请求共享,一个请求改了它,另一个请求读到被污染的值。

错误示例(数据串台):

from flask import Flask, request
app = Flask(__name__)
current_user = None          # 全局变量!

@app.route("/login")
def login():
    global current_user
    current_user = request.args.get("user")   # 请求 A 写入
    return f"logged in {current_user}"
# 请求 A 和 B 并发时,B 可能读到 A 的用户

解决方案(按场景选):

1. 能用局部变量就别用全局(最简单):

@app.route("/login")
def login():
    user = request.args.get("user")    # 请求内局部变量,天然隔离
    return f"logged in {user}"

2. 只读全局配置没问题:常量、模型实例(加载后只读推理)可以放全局。

3. 必须跨请求共享状态:用数据库、Redis 或内存缓存(带锁):

import threading
lock = threading.Lock()
counter = 0
@app.route("/inc")
def inc():
    global counter
    with lock:
        counter += 1
    return str(counter)

4. Flask 的"伪全局"requestsessiong 看起来是全局的,其实内部用上下文栈做了按请求隔离,可以放心用——g 存当前请求的临时数据正是标准做法:

from flask import g
@app.route("/x")
def x():
    g.user = "张三"      # 只对当前请求可见
    return g.user

原则:可变状态放"请求内"(局部变量/g/数据库),全局只放只读资源。

下载推广海报

圈内讨论推广海报

《全局变量在多线程下会串数据吗?怎么保证线程安全?》完整推广海报
REPLIES

回复

0 条回复
暂无回复。