问题一:
由于 Flask 代码中默认启用了多线程,如下:
```python
# 大致在 936 行
options.setdefault('use_reloader', self.debug)
options.setdefault('use_debugger', self.debug)
options.setdefault('threaded', True) # here
cli.show_server_banner(self.env, self.debug,
self.name, False)
from werkzeug.serving import run_simple
try:
run_simple(host, port, self, **options) # 此处启动 server
finally:
# reset the first request information if the development server
# reset normally. This makes it possible to restart the server
# without reloader and that stuff from an interactive shell.
self._got_first_request = False
```
然后再往下走,此处忽略,然后最终到达:
```python
def make_server(host=None, port=None, app=None, threaded=False, processes=1,
request_handler=None, passthrough_errors=False,
ssl_context=None, fd=None):
"""Create a new server instance that is either threaded, or forks
or just processes one request after another.
"""
if threaded and processes > 1:
raise ValueError("cannot have a multithreaded and "
"multi process server.")
elif threaded:
return ThreadedWSGIServer(host, port, app, request_handler,
passthrough_errors, ssl_context, fd=fd)
elif processes > 1:
return ForkingWSGIServer(host, port, app, processes, request_handler,
passthrough_errors, ssl_context, fd=fd)
else:
return BaseWSGIServer(host, port, app, request_handler,
passthrough_errors, ssl_context, fd=fd)
```
所以默认使用的是多线程方式,所以解决了问题 1
问题二:
-w 表示启动多少个 worker,简单来讲就是启动几个 flask app 副本,一种简单实现方式:
```python
# 伪代码
def start(app, worker=4, *args, **kwargs):
workers = [Process(target=app, args=()) for _ in range(worker))
for _worker in workers:
_worker.start()
# 如果你看 sanic,其实也是这个实现方式
```
所以关于 gunicorn,我的理解就是启动-w 个 flask 程序,如你描述那就是 4 个 flask 进程,至于是不是单进程多线程方式,那是另外一个问题了....