You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何锁定Flask端点,实现同一时间仅单个用户访问?

Flask端点单用户访问失效的原因及解决办法

你的问题确实和Flask的线程机制直接相关。

原因分析

默认情况下,Flask的开发服务器(Werkzeug)是多线程模式——每个进来的HTTP请求都会被分配到一个独立的线程中处理。你用普通字典locks作为全局锁标记,会遇到竞态条件:

  • 当两个用户同时请求/project1/bench1时,两个线程会同时检查locks["bench1"] == "unlocked",此时两者都会判定锁未被占用;
  • 接着两个线程都会执行locks["bench1"] = "locked",最终导致两个用户都能访问目标页面,锁机制完全失效。

普通字典不是线程安全的数据结构,多线程下的无保护读写必然会出现这类问题。

解决方案:用线程安全的锁机制

改用Python标准库threading模块提供的Lock对象,它能保证同一时间只有一个线程能获取锁,从根本上避免竞态条件。

1. 初始化线程安全锁

import threading

# 为每个bench创建独立的Lock对象
bench_locks = {
    "bench1": threading.Lock()
}

2. 修改访问端点逻辑

@app.route('/project1/bench1')
def bench1_dashboard():
    # 非阻塞式尝试获取锁:如果锁已被占用,直接返回"正在使用"页面
    if not bench_locks["bench1"].acquire(blocking=False):
        return render_template('bench_in_use.html')
    
    try:
        # 锁获取成功,返回目标页面
        return send_from_directory('templates/project1/bench1.html')
    except Exception as e:
        # 确保发生异常时也能释放锁,避免死锁
        bench_locks["bench1"].release()
        raise e

3. 修改锁释放端点逻辑

@app.route('/project1/bench1/release')
def release_bench1():
    # 检查锁是否被占用,是则释放
    if bench_locks["bench1"].locked():
        bench_locks["bench1"].release()
    return "锁已释放"

额外注意事项

  • 如果你的Flask应用部署在多进程环境(比如用Gunicorn开启多个worker进程),线程锁会失效(进程间内存不共享),此时需要用跨进程的锁方案,比如Redis分布式锁、文件锁等。
  • 页面关闭的通知可能因为网络中断、客户端异常崩溃等情况丢失,建议给锁添加超时自动释放机制:比如维护一个字典记录每个bench的占用时间,用后台定时线程检查并释放超时的锁,避免锁被永久占用。

内容的提问来源于stack exchange,提问作者handris18

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 06:41:11