2018-04-04 13:09:47 lucky404 阅读数 5724更多

分类专栏: python
 
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。

之前有阅读过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多路复用。

涉及到的源码文件

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

可以看到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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

我们主要来看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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

_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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

对于IO多路复用不熟悉的,推荐查看该文章: https://blog.csdn.net/qq546770908/article/details/53082870

flask 源码浅析(flask 如何处理请求(多线程,多进程,IO多路复用))的更多相关文章

  1. 07 flask源码剖析之用户请求过来流程

    07 Flask源码之:用户请求过来流程 目录 07 Flask源码之:用户请求过来流程 1.创建ctx = RequestContext对象 2. 创建app_ctx = AppContext对象 ...

  2. Flask源码浅析

    前言 学习一样东西,要先知其然,然后知其所以然. 这次,我们看看Flask Web框架的源码.我会以Flask 0.1的源码为例,把重点放在Flask如何处理请求上,看一看从一个请求到来到返回响应都经 ...

  3. Flask源码解析:Flask应用执行流程及原理

    WSGI WSGI:全称是Web Server Gateway Interface,WSGI不是服务器,python模块,框架,API或者任何软件,只是一种规范,描述服务器端如何与web应用程序通信的 ...

  4. Nginx源码结构及如何处理请求

    一.源码结构   1:下载安装包后,解压,可以看到目录结构,其中src目录下放的是源码       2:src源码目录下,可以看到这几个目录     mail:mail目录中存放了实现Nginx服务器 ...

  5. Flask源码解析:Flask上下文

    一.上下文(Context) 什么是上下文: 每一段程序都有很多外部变量.只有像Add这种简单的函数才是没有外部变量的.一旦你的一段程序有了外部变量,这段程序就不完整,不能独立运行.你为了使他们运行, ...

  6. 用尽洪荒之力学习Flask源码

    WSGIapp.run()werkzeug@app.route('/')ContextLocalLocalStackLocalProxyContext CreateStack pushStack po ...

  7. Flask源码剖析详解

    1. 前言 本文将基于flask 0.1版本(git checkout 8605cc3)来分析flask的实现,试图理清flask中的一些概念,加深读者对flask的理解,提高对flask的认识.从而 ...

  8. flask源码剖析系列(系列目录)

    flask源码剖析系列(系列目录) 01 flask源码剖析之werkzurg 了解wsgi 02 flask源码剖析之flask快速使用 03 flask源码剖析之threading.local和高 ...

  9. 浅谈flask源码之请求过程

    更新时间:2018年07月26日 09:51:36   作者:Dear.   我要评论   这篇文章主要介绍了浅谈flask源码之请求过程,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随 ...

随机推荐

  1. python client.py

    vi /Library/Frameworks/Python.framework/Versions//http/client.py vi /Library/Frameworks/Python.frame ...

  2. vs连接oracle

    参考: https://www.cnblogs.com/gguozhenqian/p/4262813.html

  3. orcle not like不建议使用(not like所踩过的坑!)

      1.情景展示 现在有一张表,需要将表中某字段的值不是以指定字符开头的列进行删除,如何实现? 2.问题分析 错误方案一:同事想到的是:这种方式 咱们来看一下,这个表总共有多少条数据 本来表数据总共才 ...

  4. Android Studio 之 AndroidViewModel

    AndroidViewModel是ViewModel的一个子类,可以直接调用getApplication(),由此可以访问应用的全局资源. 在 MyViewModel 这个类中,此类直接继承自 And ...

  5. 删除list集合中某些数据

    去除list集合中不符合条件的数据 List<DictVo> applyStateList = SingletonHoldResource.getInstance().getList(Fr ...

  6. [技术博客] 微信小程序的formid获取

    微信小程序的formid获取 formId的触发 微信小程序可以通过收集用户的formid,获取formid给用户主动推送微信消息.获取formid有两个途径,一个是触发一次表单提交,或者触发一次支付 ...

  7. scala 项目pom示例

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...

  8. CentOS7 下 yum 安装 Docker CE

    前言 Docker 使用越来越多,安装也很简单,本次记录一下基本的步骤. Docker 目前支持 CentOS 7 及以后的版本,内核要求至少为 3.10. Docker 官网有安装步骤,本文只是记录 ...

  9. [转帖]如何获得一个Oracle RAC数据库(从Github - oracle/vagrant-boxes) --- 暂时未测试成功 公司网络太差了..

    如何获得一个Oracle RAC数据库(从Github - oracle/vagrant-boxes) 2019-11-20 16:40:36 dingdingfish 阅读数 5更多 分类专栏: 如 ...

  10. FusionInsight大数据开发---SparkStreaming概述

    SparkStreaming概述 SparkStreaming是Spark核心API的一个扩展,它对实时流式数据的处理具有可扩展性.高吞吐量.可容错性等特点. SparkStreaming原理 Spa ...