摘要:前面兩篇講明了怎么支持多線程以及怎么開啟多線程的這篇來(lái)講講當(dāng)后端接收到請(qǐng)求后是怎么一步步封裝的類中的當(dāng)應(yīng)用啟動(dòng)后會(huì)通過(guò)接收請(qǐng)求中返回的是方法主要做了兩件事情第一件事是通過(guò)的另一個(gè)方法返回得到了一個(gè)封裝好的對(duì)象然后調(diào)用中的在最后調(diào)用了將請(qǐng)求對(duì)
前面兩篇講明了flask怎么支持多線程以及怎么開啟多線程的,這篇來(lái)講講當(dāng)后端接收到請(qǐng)求后是怎么一步步封裝的
Flask類中的wsgi_app()
當(dāng)應(yīng)用啟動(dòng)后WSGI Server會(huì)通過(guò)Flask.__call__()接收http請(qǐng)求,Flask.__call__()中返回的是wsgi_app()方法,
def wsgi_app(self, environ, start_response): ctx = self.request_context(environ) ctx.push() error = None try: try: response = self.full_dispatch_request() except Exception as e: error = e response = self.handle_exception(e) except: error = sys.exc_info()[1] raise return response(environ, start_response) finally: if self.should_ignore_error(error): error = None ctx.auto_pop(error)
wsgi_app()主要做了兩件事情:
第一件事是通過(guò)Flask的另一個(gè)方法request_context()返回得到了一個(gè)封裝好的RequsetContext對(duì)象,
ctx = self.request_context(environ),然后調(diào)用RequestContext中的push(),
class RequestContext(object):
def push(self): app_ctx = _app_ctx_stack.top if app_ctx is None or app_ctx.app != self.app: app_ctx = self.app.app_context() app_ctx.push() self._implicit_app_ctx_stack.append(app_ctx) else: self._implicit_app_ctx_stack.append(None) if hasattr(sys, "exc_clear"): sys.exc_clear() _request_ctx_stack.push(self) self.session = self.app.open_session(self.request) if self.session is None: self.session = self.app.make_null_session()
在最后調(diào)用了_request_ctx_stack.push(self),將請(qǐng)求對(duì)象推入請(qǐng)求上下文棧中
第二件事是在RequestContext的push()中調(diào)用app_ctx = self.app.app_context(),app_ctx.push(),將app推入應(yīng)用上下文棧,
深究下去時(shí)可以發(fā)現(xiàn),在RequestContext中有個(gè)app屬性,它在Flask中的request_context(),也就是在wasi_app()中調(diào)用self.request_context(environ)時(shí)被賦值,
def request_context(self, environ): return RequestContext(self, environ)
可以看到每次都傳入了self,也就是Flask對(duì)象,它在RequestContext中賦值給了self.app,所以在RequestContext push()中每次推入應(yīng)用上下文的app都是同一個(gè)
有兩點(diǎn)需要注意:
1.在web runtime情況下,請(qǐng)求上下文和應(yīng)用上下文,同時(shí)存在,同時(shí)消亡
2.創(chuàng)建完應(yīng)用后不會(huì)立即生成應(yīng)用上下文
RequestContext中放了request和session
AppContext中放了g
current_app就是AppContext對(duì)象
Local()中的__storage__這個(gè)字典格式是{thread_id:{"stack":[
所以LocalStack中的top方法返回的結(jié)果有兩個(gè):一個(gè)是RequestContext對(duì)象,一個(gè)是AppContext對(duì)象
最后拋兩個(gè)問(wèn)題,下次寫
1.明明一個(gè)線程只能處理一個(gè)請(qǐng)求,那么棧里的元素永遠(yuǎn)是在棧頂,那為什么需要用棧這個(gè)結(jié)構(gòu)?用普通變量不行嗎.
2._request_ctx_stack和_app_ctx_stack都是線程隔離的,那么為什么要分開?
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/44731.html
摘要:上次遺留了兩個(gè)問(wèn)題先說(shuō)一下自己的看法問(wèn)題明明一個(gè)線程只能處理一個(gè)請(qǐng)求那么棧里的元素永遠(yuǎn)是在棧頂那為什么需要用棧這個(gè)結(jié)構(gòu)用普通變量不行嗎和都是線程隔離的那么為什么要分開我認(rèn)為在的情況下是可以不需要棧這個(gè)結(jié)構(gòu)的即使是單線程下也不需要原本我以為在 上次遺留了兩個(gè)問(wèn)題,先說(shuō)一下自己的看法問(wèn)題:1.明明一個(gè)線程只能處理一個(gè)請(qǐng)求,那么棧里的元素永遠(yuǎn)是在棧頂,那為什么需要用棧這個(gè)結(jié)構(gòu)?用普通變量不行...
摘要:并且棧頂?shù)脑囟际堑恼?qǐng)求上下文和應(yīng)用上下文之后,我們?cè)僭谶@個(gè)環(huán)境中嵌套的應(yīng)用上下文。這時(shí)查看兩個(gè)棧的內(nèi)容,發(fā)現(xiàn)兩個(gè)棧中只有的請(qǐng)求的請(qǐng)求上下文對(duì)象和應(yīng)用上下文對(duì)象。而等一直指向棧頂?shù)恼?qǐng)求上下文對(duì)象,分別引用請(qǐng)求上下文的和。 在Flask中處理請(qǐng)求時(shí),應(yīng)用會(huì)生成一個(gè)請(qǐng)求上下文對(duì)象。整個(gè)請(qǐng)求的處理過(guò)程,都會(huì)在這個(gè)上下文對(duì)象中進(jìn)行。這保證了請(qǐng)求的處理過(guò)程不被干擾。處理請(qǐng)求的具體代碼如下: de...
摘要:如果設(shè)置為,命令將激活模式,執(zhí)行會(huì)啟用交互式調(diào)試器和代碼自動(dòng)重載。也可以通過(guò)變量單獨(dú)控制,表示啟用,表示禁用通過(guò)設(shè)置環(huán)境變量略通過(guò)設(shè)置環(huán)境變量略自定義命令命令基于庫(kù)實(shí)現(xiàn)。 應(yīng)用發(fā)現(xiàn) flask命令在Flask庫(kù)安裝后可使用,使用前需要正確配置FLASK_APP環(huán)境變量以告知用戶程序所在位置。不同平臺(tái)設(shè)置方式有所不同。 Unix Bash (Linux, Mac, etc.): $ ex...
摘要:本文就主要針對(duì)一個(gè)應(yīng)用的運(yùn)行過(guò)程進(jìn)行簡(jiǎn)要分析,后續(xù)文章還會(huì)對(duì)框架的一些具體問(wèn)題進(jìn)行分析。所有的請(qǐng)求處理過(guò)程,都會(huì)在這個(gè)上下文對(duì)象中進(jìn)行。和一些全局變量注意當(dāng)進(jìn)入這個(gè)上下文對(duì)象時(shí),會(huì)觸發(fā)。 相信很多初學(xué)Flask的同學(xué)(包括我自己),在閱讀官方文檔或者Flask的學(xué)習(xí)資料時(shí),對(duì)于它的認(rèn)識(shí)是從以下的一段代碼開始的: from flask import Flask app = Flask(...
摘要:瀏覽器渲染進(jìn)程瀏覽器內(nèi)核進(jìn)程,內(nèi)部是多線程的默認(rèn)每個(gè)頁(yè)面一個(gè)進(jìn)程,互不影響。事件觸發(fā)線程歸屬于瀏覽器而不是引擎,用來(lái)控制事件循環(huán)可以理解成引擎自己都忙不過(guò)來(lái),需要瀏覽器另開線程協(xié)助。 線程和進(jìn)程 進(jìn)程和線程的概念可以這樣理解: 進(jìn)程是一個(gè)工廠,工廠有它的獨(dú)立資源--工廠之間相互獨(dú)立--線程是工廠中的工人,多個(gè)工人協(xié)作完成任務(wù)--工廠內(nèi)有一個(gè)或多個(gè)工人--工人之間共享空間 工廠有多個(gè)工人...
閱讀 2511·2021-09-26 10:18
閱讀 3386·2021-09-22 10:02
閱讀 3183·2019-08-30 15:44
閱讀 3326·2019-08-30 15:44
閱讀 1831·2019-08-29 15:25
閱讀 2572·2019-08-26 14:04
閱讀 2035·2019-08-26 12:15
閱讀 2437·2019-08-26 11:43