bigywater.tech
Flask · 2

app.run() 的启动过程

一行 app.run() 就能把应用跑起来,但它到底启动了什么?监听哪里?debug 多了哪些东西?这篇起真实进程,看日志、看进程、看监听端口。

2
debug=True 时的进程数(重载器父进程 + 工作子进程)
511 → 1018 ms
2 个并发慢请求的总耗时:threaded=True → False
127.0.0.1
app.run 默认监听的地址

默认启动

实测 · 本机执行输出
  app.py:
      1 | import os, time, threading
      2 | from flask import Flask
      3 | app = Flask(__name__)
      4 | @app.get("/")
      5 | def index(): return f"pid={os.getpid()} run_main={os.environ.get('WERKZEUG_RUN_MAIN')}\n"
      6 | @app.get("/slow")
      7 | def slow():
      8 |     time.sleep(0.5); return "slow done\n"
      9 | if __name__ == "__main__":
     10 |     app.run(port=int(os.environ["PORT"]), debug=os.environ.get("DBG") == "1", host=os.environ.get("HOST", "127.0.0.1"), threaded=os.environ.get("THR", "1") == "1")
  GET / → 200 pid=30945 run_main=None
  启动时服务器打印的内容(app.run 往 stderr 写):
     * Serving Flask app 'app'
     * Debug mode: off
    WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
     * Running on http://127.0.0.1:9601
    Press CTRL+C to quit
    127.0.0.1 - - [02/Oct/2026 11:00:43] "GET / HTTP/1.1" 200 -
  监听地址: ['127.0.0.1:9601']
  相关进程数 1:
    30945 30944 python@3.14/3.14.7/Frameworks/Python.framework/Versions/3.14/Resources/Python.app/Conten

上一篇:Flask(__name__) 到底初始化了什么。

debug=True 与自动重载

实测 · 本机执行输出
  GET / → pid=30955 run_main=true
  相关进程数 2:
    30952 30944 python@3.14/3.14.7/Frameworks/Python.framework/Versions/3.14/Resources/Python.app/Conten
    30955 30952 python@3.14/3.14.7/Frameworks/Python.framework/Versions/3.14/Resources/Python.app/Conten
  启动信息:
     * Serving Flask app 'app'
     * Debug mode: on
    WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
     * Running on http://127.0.0.1:9602
    Press CTRL+C to quit
     * Restarting with stat
     * Debugger is active!
     * Debugger PIN: ***-***-***
    127.0.0.1 - - [02/Oct/2026 11:00:44] "GET / HTTP/1.1" 200 -
  改动 app.py 后 0.64 秒日志出现重载;再请求:pid=30980 run_main=true
  重载相关日志:
     * Restarting with stat
     * Debugger is active!
     * Debugger PIN: ***-***-***
     * Detected change in '<实验目录>/fltmp/f2/app.py', reloading
    …(共 7 行)

host

实测 · 本机执行输出
  host=127.0.0.1  → lsof 看到的监听:['127.0.0.1:9603']
  host=0.0.0.0    → lsof 看到的监听:['*:9604']

threaded

实测 · 本机执行输出
  threaded=True  总耗时 505, 513, 511 ms(中位数 511)
  threaded=False 总耗时 1014, 1023, 1018 ms(中位数 1018)

flask run

实测 · 本机执行输出
  flask --app app run --port 9607 → GET / 200 pid=31032 run_main=None
  启动信息:
     * Serving Flask app 'app'
     * Debug mode: off
    WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
     * Running on http://127.0.0.1:9607
    Press CTRL+C to quit
    127.0.0.1 - - [02/Oct/2026 11:00:52] "GET / HTTP/1.1" 200 -
  加 --debug:
     * Debug mode: on
     * Debugger is active!
     * Debugger PIN: ***-***-***

分步演示

app.run()
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.7 / Flask 3.1.3 / Werkzeug 3.1.9 / Jinja2 3.1.6 / SQLAlchemy 2.1.1 / gunicorn 26.2.0(都装在自己的虚拟环境里);大多数实验用 Flask 的 test_client(直接调用 WSGI 应用,不经过网络),需要真实 HTTP 时另起 gunicorn 或开发服务器(端口 9600 以上,本机 127.0.0.1);计时用 time.perf_counter,数字每次运行会有小幅抖动。这里的开发服务器就是 Werkzeug 3.1.9 自带的服务器
    • 没有验证:Windows 与 Linux 上的重载行为、watchdog 库存在时重载器的差别(本机的日志是 stat 重载器)、ssl_context 参数、processes 参数、Debugger PIN 的计算方式(日志里已打码)
    京ICP备2026067502号-1京公网安备11010502063487号