flask 源码浅析(flask 如何处理请求(多线程,多进程,IO多路复用))
2018-04-04 13:09
375 查看
之前有阅读过tornado 底层的实现,tornado 为了解决C10K 问题(没听说过C10K问题的请查看: http://www.360doc.com/content/13/0522/18/1542811_287328391.shtml),在Linux 平台下是使用了epoll(python2.6 开始支持epoll),unix 平台下 tornado 使用了kque , 由于flask 之前没有看过底层的实现,因此趁着清明假期看了一下flask,到底是来一个请求使用一个线程呢,还是进程呢,还是IO多路复用。
涉及到的源码文件
首先肯定要先看入口函数啦
该函数通过
可以看到flask 为我们提供了三种方式来处理请求
1 使用多线程来进行处理
2 使用多进程来进行处理
3 使用poll 或者 select IO多路复用的方式进行处理
下面有个方法
我们主要来看
对于IO多路复用不熟悉的,推荐查看该文章: https://blog.csdn.net/qq546770908/article/details/53082870
涉及到的源码文件
site-packages/flask/app.py, site-packages/werkzeug/serving.py, Lib/socketserver.py
首先肯定要先看入口函数啦
app.py里面的 run 函数
def run(self, host=None, port=None, debug=None, **options):
该函数通过
run_simple(host, port, self, **options)启动了socket 服务器(
无论是哪个web框架,其实底层都是使用socketserver 监听在某个套接字上来处理请求的)
run_simple然后到调用
serving.py里面的
make_server
make_server源码定义如下:
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)
可以看到flask 为我们提供了三种方式来处理请求
1 使用多线程来进行处理
2 使用多进程来进行处理
3 使用poll 或者 select IO多路复用的方式进行处理
BaseWSGIServer这个类是使用IO 多路复用的
下面有个方法
start_forever
def serve_forever(self): self.shutdown_signal = False try: HTTPServer.serve_forever(self) except KeyboardInterrupt: pass finally: self.server_close()
我们主要来看
HttpServer.serve_forever方法
def serve_forever(self, poll_interval=0.5): """Handle one request at a time until shutdown. Polls for shutdown every poll_interval seconds. Ignores self.timeout. If you need to do periodic tasks, do them in another thread. """ self.__is_shut_down.clear() try: # XXX: Consider using another file descriptor or connecting to the # socket to wake this up instead of polling. Polling reduces our # responsiveness to a shutdown request and wastes cpu at all other # times. with _ServerSelector() as selector: selector.register(self, selectors.EVENT_READ) while not self.__shutdown_request: ready = selector.select(poll_interval) if ready: self._handle_request_noblock() self.service_actions() finally: self.__shutdown_request = False self.__is_shut_down.set()
_ServerSelector()定义了 到底该使用select 还是 poll
# poll/select have the advantage of not requiring any extra file descriptor, # contrarily to epoll/kqueue (also, they require a single syscall). if hasattr(selectors, 'PollSelector'): _ServerSelector = selectors.PollSelector else: _ServerSelector = selectors.SelectSelector
对于IO多路复用不熟悉的,推荐查看该文章: https://blog.csdn.net/qq546770908/article/details/53082870
相关文章推荐
- .net core 源码解析-web app是如何启动并接收处理请求(二) kestrel的启动
- .net core 源码解析-web app是如何启动并接收处理请求
- 从Nginx的Web请求处理机制中剖析多进程、多线程、异步IO
- tio-http-server 源码浅析(二)Http请求的处理HttpRequestHandler
- flask session session已过期,再发送ajax请求如何处理?
- .net core 源码解析-web app是如何启动并接收处理请求
- Nginx源码结构及如何处理请求
- Struts2源码浅析-请求处理
- .net core 源码解析-web app是如何启动并接收处理请求(二) kestrel的启动
- Struts2源码浅析-请求处理(转)
- 使用Oracle SQL Developer连接数据库时,提示“执行请求的操作时遇到错误:IO 错误: The Network Adapter could not establish”,不知如何处理
- tio-http-server 源码浅析(二)Http请求的处理HttpRequestHandler
- SpringMVC源码剖析(二)SpringMVC是如何处理请求的
- 从源码角度分析nodejs如何处理一个HTTP请求
- Struts2源码浅析-请求处理
- Struts2源码浅析-请求处理
- Alluxio源码分析:RPC框架浅析(三)
- Spring MVC源码分析(续)——请求处理
- Nginx如何处理一个请求
- Linux 多线程应用中如何编写安全的信号处理函数