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

Werkzeug BaseWSGIServer线程处理请求后挂起,终端无响应问题求助

Werkzeug BaseWSGIServer线程处理请求后挂起,终端无响应问题求助

这问题卡了我快一周了,啥正事都没法干——要是你有Python/Werkzeug/Flask/多线程相关经验,求帮忙看看...

平时咱们跑Flask应用,都是开个单独终端输入py flask.py,手动启动,再用Ctrl-C手动关停。但我的Python应用只在特定场景下需要这个本地服务器,比如用Spotify的授权码流程获取令牌,之后才能用他们的Web API发有效请求。

我的auth_server.py文件负责这块逻辑,里面有个继承自Thread的LocalServerThread类,是直接抄的八年前的一个Stack Overflow回答——那时候Windows平台下这是唯一能用的方案,但现在看来只能算半残示例了。

先上这个类的完整代码:

from werkzeug.serving import make_server

class ServerThread(threading.Thread):
    THREAD_NAME = 'LocalServerThread'

    def __init__(self, app):
        threading.Thread.__init__(self, name=LocalServerThread.THREAD_NAME)
        self.server = make_server('127.0.0.1', 8080, app)
        self.ctx = app.app_context()
        self.ctx.push()

    def run(self):
        log.info('starting server')
        self.server.serve_forever()

    def shutdown(self):
        self.server.shutdown()

def start_server():
    global server
    app = flask.Flask('myapp')
    # App routes defined here
    server = ServerThread(app)
    server.start()
    log.info('server started')

def stop_server():
    global server
    server.shutdown()

这是auth_server.py里剩下的相关代码:

def start_local_http_server():
    app = Flask(__name__)

    @app.route('/')
    def home():

    @app.route('/login')
    def login():

    @app.route('/callback')
    def callback():

    global server
    server = LocalServerThread(app)
    server.start()
    print(fr'Started {LocalServerThread.THREAD_NAME}, serving: http://127.0.0.1:8080')

def stop_local_http_server():
    server.shutdown()

这是我main.py里调用这块的实际代码:

if not auth_server.validate_token(reject=True):
    auth_server.start_local_http_server()

    time.sleep(4)

    auth_server.stop_local_http_server()
    
    print('Finally Done')

重点来了,问题就出在这...

我用py ./main.py运行程序,如果啥都不干让它自己跑,shutdown能正常工作,服务器也能正确关停,没问题。

但要是在主线程sleep的4秒里,我访问任意路由('/', '/login', '/callback'),服务器成功返回页面后,程序执行到self.server.shutdown()就会卡住,要等90到300秒才会继续走到主线程的print('Finally Done')。这段时间终端就一直僵在那,程序死活不退出:

终端挂起时的状态

这真的快把我逼疯了,调试也摸不着头脑。self.server.shutdown()会进到socketserver.py里的BaseServer的shutdown方法,但再往下就没法单步调试了,感觉像是在等什么东西...我把调用栈列出来了:

两种情况的调用栈对比(调试到无法继续前的状态):

左边是正常运行(没访问路由),右边是sleep期间访问了'/':

未访问路由时的调用栈 访问路由后的调用栈

备注:我用的是Windows系统。

有没有懂行的大佬能看出问题出在哪?这不仅能帮我解决麻烦,估计也能帮到以后遇到同样问题的人...

备注:内容来源于stack exchange,提问作者The-Stanislav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 15:09:50