中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

網(wǎng)站服務(wù)器服務(wù)商3d建模培訓(xùn)班一般多少錢

網(wǎng)站服務(wù)器服務(wù)商,3d建模培訓(xùn)班一般多少錢,手機(jī)銷售網(wǎng)站制作,南通網(wǎng)站制作系統(tǒng)一、local對(duì)象 背景: 多線成并發(fā)操作一個(gè)變量,會(huì)導(dǎo)致數(shù)據(jù)錯(cuò)亂,可以使用互斥鎖加鎖處理數(shù)據(jù)不安全的情況 (臨界區(qū)) 解決: 使用local對(duì)象處理,多個(gè)線程操作的變量是local對(duì)象,就不會(huì)…

一、local對(duì)象

背景:
多線成并發(fā)操作一個(gè)變量,會(huì)導(dǎo)致數(shù)據(jù)錯(cuò)亂,可以使用互斥鎖加鎖處理數(shù)據(jù)不安全的情況 (臨界區(qū))

解決:
使用local對(duì)象處理,多個(gè)線程操作的變量是local對(duì)象,就不會(huì)有并發(fā)安全的問(wèn)題。因?yàn)樗幚砹瞬l(fā)安全的問(wèn)題---->請(qǐng)求統(tǒng)一放在一個(gè)大字典中,key值是線程id號(hào),value是個(gè)字典。

# {111:{'name':jack},222:{'name':roma}}
l=local()
l.name='jack'---->l[111][name]
l.name='roma'---->l[222][name]

1.基本使用
不使用local,多線程并發(fā)操作,數(shù)據(jù)錯(cuò)亂

import time
from threading import Thread
class Local():passl = Local()def task(name):l.name = name time.sleep(1)print('在線程內(nèi)的名字是:', name, 'l對(duì)象中的名字大概率不一樣', l.name)if __name__ == '__main__':for i in range(10):t = Thread(target=task, args=['jack' + str(i) + '號(hào)', ])t.start() # 等待所有線程都執(zhí)行完成再執(zhí)行下面代碼time.sleep(6)print(l)

使用local

import time
from threading import Thread
from threading import local# 定義一個(gè)全局變量,并發(fā)安全的local,多個(gè)線程操作,不會(huì)錯(cuò)亂,因?yàn)槊總€(gè)線程用的都是自己的數(shù)據(jù)
l = local()def task(name):l.name = nametime.sleep(1)print('在線程內(nèi)的名字是:', name, 'l對(duì)象中的名字也是', l.name)if __name__ == '__main__':for i in range(10):t = Thread(target=task, args=['jack' + str(i) + '號(hào)', ])t.start()# 等待所有線程都執(zhí)行完成再執(zhí)行下面代碼time.sleep(6)print(l)

2.自己寫一個(gè)local類,線程和協(xié)程并發(fā)安全

通過(guò)字典自定義threading.local(函數(shù))

from threading import get_ident,Thread
import time
storage = {}
def set(k,v):ident = get_ident()  # 線程id號(hào)if ident in storage:storage[ident][k] = velse:storage[ident] = {k:v}
def get(k):ident = get_ident()return storage[ident][k]
def task(arg):set('val',arg) #v = get('val')print(v)# 10個(gè)線程跑完,最終storage={123:{val:0},222:{val:1},333:{val:2},444:{val:3}.....}
for i in range(10):t = Thread(target=task,args=(i,))t.start()

使用面向?qū)ο?/strong>:

from threading import get_ident,Thread
import time
class Local(object):storage = {}def set(self, k, v):ident = get_ident()if ident in Local.storage:Local.storage[ident][k] = velse:Local.storage[ident] = {k: v}def get(self, k):ident = get_ident()return Local.storage[ident][k]
obj = Local()
def task(arg):obj.set('val',arg)v = obj.get('val')print(v)
for i in range(10):t = Thread(target=task,args=(i,))t.start()

通過(guò)__setattr__和__getattr__方法實(shí)現(xiàn)

from threading import get_ident,Thread
import time
class Local(object):storage = {}def __setattr__(self, k, v):ident = get_ident()if ident in Local.storage:Local.storage[ident][k] = velse:Local.storage[ident] = {k: v}def __getattr__(self, k):ident = get_ident()return Local.storage[ident][k]
obj = Local()
def task(arg):obj.val = argprint(obj.val)
for i in range(10):t = Thread(target=task,args=(i,))t.start()

每個(gè)local對(duì)象用自己的存儲(chǔ)空間(字典)

from threading import get_ident, Thread
import timeclass Local(object):def __init__(self):# self.storage={}  # 不能這樣寫 會(huì)遞歸object.__setattr__(self, 'storage', {})def __setattr__(self, k, v):ident = get_ident()  # 獲取線程id號(hào)if ident in self.storage:self.storage[ident][k] = velse:self.storage[ident] = {k: v}    #def __getattr__(self, k):ident = get_ident()return self.storage[ident][k]obj = Local()def task(name):obj.name = nameprint(obj.name)for i in range(10):t = Thread(target=task, args=(i,))t.start()

兼容線程和協(xié)程

try:from greenlet import getcurrent as get_ident
except Exception as e:from threading import get_identfrom threading import Thread
import time
class Local(object):def __init__(self):object.__setattr__(self,'storage',{})def __setattr__(self, k, v):ident = get_ident()if ident in self.storage:self.storage[ident][k] = velse:self.storage[ident] = {k: v}def __getattr__(self, k):ident = get_ident()return self.storage[ident][k]
obj = Local()
def task(arg):obj.val = argobj.xxx = argprint(obj.val)
for i in range(10):t = Thread(target=task,args=(i,))t.start()

二、flask上下文源碼分析

請(qǐng)求上下文執(zhí)行流程(ctx):

-0 flask項(xiàng)目一啟動(dòng),有6個(gè)全局變量-_request_ctx_stack:LocalStack對(duì)象---->封裝了local-_app_ctx_stack :LocalStack對(duì)象-request : LocalProxy對(duì)象-session : LocalProxy對(duì)象-1 請(qǐng)求來(lái)了 app.__call__()---->內(nèi)部執(zhí)行:self.wsgi_app(environ, start_response)-2 wsgi_app()-2.1 執(zhí)行:ctx = self.request_context(environ):返回一個(gè)RequestContext對(duì)象,并且封裝了request(當(dāng)次請(qǐng)求的request對(duì)象),session-2.2 執(zhí)行: ctx.push():RequestContext對(duì)象的push方法-2.2.1 push方法中中間位置有:_request_ctx_stack.push(self),self是ctx對(duì)象-2.2.2 去_request_ctx_stack對(duì)象的類中找push方法(LocalStack中找push方法)-2.2.3 push方法源碼:def push(self, obj):#通過(guò)反射找self._local,在init實(shí)例化的時(shí)候生成的:self._local = Local()#Local()flask封裝的支持線程和協(xié)程的local對(duì)象# 一開(kāi)始取不到stack,返回Nonerv = getattr(self._local, "stack", None)if rv is None:#走到這,self._local.stack=[],rv=self._local.stackself._local.stack = rv = []# 把ctx放到了列表中#self._local={'線程id1':{'stack':[ctx,]},'線程id2':{'stack':[ctx,]},'線程id3':{'stack':[ctx,]}}rv.append(obj)return rv-3 如果在視圖函數(shù)中使用request對(duì)象,比如:print(request)-3.1 會(huì)調(diào)用request對(duì)象的__str__方法,request類是:LocalProxy-3.2 LocalProxy中的__str__方法:lambda x: str(x._get_current_object())-3.2.1 內(nèi)部執(zhí)行self._get_current_object()-3.2.2 _get_current_object()方法的源碼如下:def _get_current_object(self):if not hasattr(self.__local, "__release_local__"):#self.__local()  在init的時(shí)候,實(shí)例化的,在init中:object.__setattr__(self, "_LocalProxy__local", local)# 用了隱藏屬性#self.__local 實(shí)例化該類的時(shí)候傳入的local(偏函數(shù)的內(nèi)存地址:partial(_lookup_req_object, "request"))#加括號(hào)返回,就會(huì)執(zhí)行偏函數(shù),也就是執(zhí)行_lookup_req_object,不需要傳參數(shù)了#這個(gè)地方的返回值就是request對(duì)象(當(dāng)此請(qǐng)求的request,沒(méi)有亂)return self.__local()try:return getattr(self.__local, self.__name__)except AttributeError:raise RuntimeError("no object bound to %s" % self.__name__)-3.2.3 _lookup_req_object函數(shù)源碼如下:def _lookup_req_object(name):#name是'request'字符串#top方法是把第二步中放入的ctx取出來(lái),因?yàn)槎荚谝粋€(gè)線程內(nèi),當(dāng)前取到的就是當(dāng)次請(qǐng)求的ctx對(duì)象top = _request_ctx_stack.topif top is None:raise RuntimeError(_request_ctx_err_msg)#通過(guò)反射,去ctx中把request對(duì)象返回return getattr(top, name)-3.2.4 所以:print(request) 實(shí)質(zhì)上是在打印當(dāng)此請(qǐng)求的request對(duì)象的__str__-4 如果在視圖函數(shù)中使用request對(duì)象,比如:print(request.method):實(shí)質(zhì)上是取到當(dāng)次請(qǐng)求的reuquest對(duì)象的method屬性-5 最終,請(qǐng)求結(jié)束執(zhí)行: ctx.auto_pop(error),把ctx移除掉

其他的東西:

-session:-請(qǐng)求來(lái)了opensession-ctx.push()---->也就是RequestContext類的push方法的最后的地方:if self.session is None:#self是ctx,ctx中有個(gè)app就是flask對(duì)象,   self.app.session_interface也就是它:SecureCookieSessionInterface()session_interface = self.app.session_interfaceself.session = session_interface.open_session(self.app, self.request)if self.session is None:#經(jīng)過(guò)上面還是None的話,生成了個(gè)空sessionself.session = session_interface.make_null_session(self.app)-請(qǐng)求走了savesession-response = self.full_dispatch_request() 方法內(nèi)部:執(zhí)行了before_first_request,before_request,視圖函數(shù),after_request,savesession-self.full_dispatch_request()---->執(zhí)行:self.finalize_request(rv)-----》self.process_response(response)----》最后:self.session_interface.save_session(self, ctx.session, response)-請(qǐng)求擴(kuò)展相關(guān)before_first_request,before_request,after_request依次執(zhí)行-信號(hào)的觸發(fā)信號(hào)名.send()-flask有一個(gè)請(qǐng)求上下文,一個(gè)應(yīng)用上下文-ctx:-是:RequestContext對(duì)象:封裝了request和session-調(diào)用了:_request_ctx_stack.push(self)就是把:ctx放到了那個(gè)位置-app_ctx:-是:AppContext(self) 對(duì)象:封裝了當(dāng)前的app和g-調(diào)用 _app_ctx_stack.push(self) 就是把:app_ctx放到了那個(gè)位置-g是個(gè)什么鬼?專門用來(lái)存儲(chǔ)用戶信息的g對(duì)象,g的全稱的為global g對(duì)象在一次請(qǐng)求中的所有的代碼的地方,都是可以使用的(當(dāng)次請(qǐng)求中傳遞一些數(shù)據(jù))-代理模式-request和session就是代理對(duì)象,用的就是代理模式-g對(duì)象和session的區(qū)別g對(duì)象只對(duì)當(dāng)次請(qǐng)求有效(當(dāng)此請(qǐng)求內(nèi)有效)session:可以跨請(qǐng)求,該用戶的多次請(qǐng)求中都可以使用

總結(jié):
1 flask中間件,使用請(qǐng)求擴(kuò)展,完成django中間件的功能

2 快速生成當(dāng)前項(xiàng)目的依賴(兩種方案)

  • pipreqs

3 函數(shù)和方法的區(qū)別

  • 面向?qū)ο笾杏蟹椒ǖ母拍?/li>
  • 綁定給對(duì)象的,綁定給類的方法
  • 特殊之處是自動(dòng)傳值
  • 方法有可能是函數(shù)(對(duì)象的綁定方法,如果類來(lái)調(diào)用,就是函數(shù))

4 偏函數(shù) partial

  • 提前給函數(shù)傳值

5 local對(duì)象

  • 解決并發(fā)安全的問(wèn)題
  • 多條線程操作同一個(gè)變量,會(huì)出現(xiàn)數(shù)據(jù)安全問(wèn)題,解決該問(wèn)題,需要加鎖
  • 每條線程操作的都是自己線程的數(shù)據(jù)
  • threading包下的local類---->實(shí)例化得到對(duì)象---->多線程并發(fā)操作---->數(shù)據(jù)不會(huì)錯(cuò)亂

6 自定義local對(duì)象

self.name='lqz'  # 會(huì)觸發(fā)__setattr__---->會(huì)出現(xiàn)遞歸
setattr(self,'name','lqz')  # 會(huì)出現(xiàn)遞歸
object.__setattr__(self,'name','lqz')  # 不會(huì)出現(xiàn)遞歸
self.__dict__()  # 屬性字典,也不會(huì)出現(xiàn)遞歸

7 flask請(qǐng)求上下文:RequestContext---->ctx:request,session,flash

8 flask應(yīng)用上下文:AppContext---->app_ctx:當(dāng)前app,g

9 ctx對(duì)象:請(qǐng)求上下文,flask整個(gè)請(qǐng)求的流程

請(qǐng)求來(lái)了---->app()---->觸發(fā)Flask類的__call__方法---->app.wsgi_app()ctx = self.request_context(environ) # ctx中包含當(dāng)此請(qǐng)求的request,session,把ctx放到了local對(duì)象中,來(lái)一個(gè)請(qǐng)求就放一次,local處理了并發(fā)安全,所以自己放的都是自己的,相互不影響response = self.full_dispatch_request()# 執(zhí)行請(qǐng)求擴(kuò)展,執(zhí)行視圖函數(shù)或者視圖類,處理了session,還有信號(hào)不管在整個(gè)過(guò)程中是否出異常,ctx都從local對(duì)象上移除

10 flask請(qǐng)求上下文源碼分析

1 請(qǐng)求來(lái)了執(zhí)行---->app()---->觸發(fā)類的__call__---->self.wsgi_app(environ, start_response)--->2 ctx = self.request_context(environ)---->封裝了request和session3 ctx.push()---->_request_ctx_stack.push(self)---->self是ctx4 _request_ctx_stack是LocalStack類的對(duì)象---->push
5 LocalStack的push方法源碼def push(self, obj):rv = getattr(self._local, "stack", None)if rv is None:self._local.stack = rv = []# self._local={'線程id1':{'stack':[ctx,]},'線程id2':{'stack':[ctx,]},'線程id3':{'stack':[ctx,]}}rv.append(obj)return rv6 LocalStack對(duì)像中的  _local--->init初始化出來(lái)的
self._local = Local() # 咱們自己寫的可以多線程并發(fā)訪問(wèn)的Local7 local={線程或協(xié)程id號(hào):{stack:[ctx]},線程或協(xié)程id號(hào):{stack:[ctx]}}
local.stack---->取stack的值,在不同協(xié)程下,取到的是自己的8 在視圖函數(shù)中使用request,session---->都是當(dāng)此請(qǐng)求的request和session,但是我們使用了全局變量。打印的真的是當(dāng)次請(qǐng)求的Request類的對(duì)象,但實(shí)際上request根本不是Request類的對(duì)象,LocalProxy類的對(duì)象,LocalProxy類重寫了__str__9 print(request)的時(shí)候---->類的__str__10 LocalProxy把所有的魔法方法都重寫了,因?yàn)樗莻€(gè)代理類11 request = LocalProxy(partial(_lookup_req_object, "request"))
init---->def __init__(self, local, name=None):---->object.__setattr__(self, "_LocalProxy__local", local)--->local就是偏函數(shù)12 LocalProxy---》__str__--->_get_current_object()是LocalProxy類的方法13 LocalProxy._get_current_object()---return self.__local()--》加括號(hào)執(zhí)行偏函數(shù)---》partial(_lookup_req_object, "request")()--->_lookup_req_object('request')14 返回了當(dāng)前線程所在的ctx中的request對(duì)象15 request.method-->就是當(dāng)前線程的request對(duì)象的method方法16 在視圖函數(shù)中打印print(session)--->是當(dāng)此請(qǐng)求的session# 應(yīng)用上下文
# g到底是什么,是一個(gè)全局變量,放和取在當(dāng)次請(qǐng)求中的數(shù)據(jù)# session:open_session   save_session# 信號(hào)的觸發(fā)位置
# 請(qǐng)求擴(kuò)展中三個(gè):的執(zhí)行位置
http://m.risenshineclean.com/news/58020.html

相關(guān)文章:

  • 鄭州專業(yè)網(wǎng)站設(shè)計(jì)商丘網(wǎng)絡(luò)推廣外包
  • 互聯(lián)網(wǎng)定制網(wǎng)站網(wǎng)站優(yōu)化排名推廣
  • 做瞹視頻網(wǎng)站網(wǎng)站收錄情況
  • 辦網(wǎng)站需流程網(wǎng)絡(luò)推廣一個(gè)月的收入
  • 網(wǎng)站建設(shè)圖文教程網(wǎng)站如何提交百度收錄
  • 照片做視頻模板下載網(wǎng)站seo外包多少錢
  • 深圳 服裝 網(wǎng)站建設(shè)青島百度網(wǎng)站排名
  • 清溪網(wǎng)站仿做海外推廣專員
  • 網(wǎng)站建設(shè) 模板中心如何創(chuàng)建網(wǎng)站?
  • 怎么做響應(yīng)式網(wǎng)站搜索百度
  • wordpress閉站網(wǎng)站營(yíng)銷外包哪家專業(yè)
  • 中國(guó)建設(shè)銀行手機(jī)appwindows優(yōu)化大師是哪個(gè)公司的
  • 網(wǎng)站內(nèi)容被攻擊該怎么做安徽seo優(yōu)化
  • 淘寶做鏈接的網(wǎng)站長(zhǎng)沙seo霜天
  • 自適應(yīng)網(wǎng)站建設(shè)推薦淘寶站內(nèi)推廣方式有哪些
  • 蘇州市網(wǎng)站優(yōu)化優(yōu)化大師是什么軟件
  • 怎么做免費(fèi)推廣網(wǎng)站武漢新聞最新消息
  • 江蘇網(wǎng)站制作企業(yè)最近新聞報(bào)道
  • 美食網(wǎng)站首頁(yè)模板自己怎么開(kāi)電商平臺(tái)
  • 深圳別墅設(shè)計(jì)公司首選優(yōu)化設(shè)計(jì)六年級(jí)下冊(cè)數(shù)學(xué)答案
  • 長(zhǎng)安東莞網(wǎng)站推廣線上推廣平臺(tái)有哪些
  • 尋找鄭州網(wǎng)站建設(shè)公司網(wǎng)站推廣廣告
  • 博州住房和城鄉(xiāng)建設(shè)局網(wǎng)站網(wǎng)頁(yè)設(shè)計(jì)自學(xué)要多久
  • 做動(dòng)漫游戲網(wǎng)站網(wǎng)站怎么創(chuàng)建
  • 前端做項(xiàng)目有哪些網(wǎng)站全網(wǎng)營(yíng)銷圖片
  • 網(wǎng)站建設(shè)支出賬務(wù)處理推廣形式
  • 如何快速做企業(yè)網(wǎng)站包括商城網(wǎng)頁(yè)分析工具
  • 輕淘客一鍵做網(wǎng)站seo關(guān)鍵詞優(yōu)化技巧
  • 那個(gè)網(wǎng)站做720度效果圖互聯(lián)網(wǎng)推廣員是做什么
  • 網(wǎng)站建設(shè)公司排行杭州什么平臺(tái)推廣效果最好