By using local objects, analysis flask in the global request object to a different view of the mythical function is not chaos - to assist interpretation flask source

:: fask the problem is global request for mythical Each view function is a request, but the request did not cause data disorder phenomenon? ?

# Do local, open 10 threads simultaneously for global wzg modification, in this case, I look at the result of the execution will be like? 
from Threading Import the Thread
 Import Time 
WZG = -1
 DEF Task (Arg):
     , Ltd. Free Join WZG 

    WZG = Arg
     # blocked for a while, the value of the finished thread, which thread to execute the final implementation of the right, the results will modify the global wzg, other threads Review of the results will be tampered with, so the results are all the same 
    the time.sleep (2 )
     Print (WZG) 

for I in Range (10 ): 
    T = the Thread (target = Task, args = (I,)) 
    t.start ( ) 
'' ' 
# 9 all results, so other threads modifications wzg has been tampered with, 
cause of this situation because:
Multiple threads operating globally in the same variable wzg, without any mark can be distinguished from that of the threads modifies what will be the last to perform in front of the thread other threads to modify the value of all the times the value of the repair, the result of confusion caused by 
so print the results last thread modifies the value of the 
flask in the request, session is also a global variable for each request mythical view of not mess with? 
Here we take a look at the use of local objects 
' ''
# The local objects
 from Threading Import the Thread
 from Threading Import local
 '' ' 
distinguished based on the thread, which is equivalent to storage {' thread id1 ': {' args': 1}, ' thread id2': { 'args': 2}, 'thread id3': { 'args': } 3} 
such print out is the value corresponding to the threads, so to prevent data confusion 
# # {Arg:. 1} 
' '' 
Import Time 
LQZ = local ()
 DEF Task (Arg): 
    lqz.arg = Arg 
    the time.sleep ( 2 )
     Print (lqz.arg) 

for I in Range (10 ): 
    T = the Thread (target = Task, args = (I,)) 
    T.start()
#自定义local,函数版
from threading import get_ident,Thread  #get_ident线程的ID号
import time
storage = {}
def set(k,v):
    #获取线程的id号
    # storage={'线程id1': {'args': 1}, '线程id2': {'args': 2}, '线程id3': {'args': 3}}
    #这样子存起来的值就对应各自的线程
    ident = get_ident()
    print(ident)
    if ident in storage:
        storage[ident][k] = v
    else:
        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)

for i in range(10):
    t = Thread(target=task,args=(i,))
    t.start()
#面向对象版的local
from threading import get_ident,Thread
import time
#{'线程id1': {'args': 1}, '线程id2': {'args': 2}, '线程id3': {'args': 3}}
class Local(object):
    storage = {}
    def set(self, k, v):
        ident = get_ident()
        if ident in Local.storage:
            Local.storage[ident][k] = v
        else:
            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')
    time.sleep(1)
    print(v)
for i in range(10):
    t = Thread(target=task,args=(i,))
    t.start()
#改进版本1
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] = v
        else:
            Local.storage[ident] = {k: v}
    def __getattr__(self, k):
        ident = get_ident()
        return Local.storage[ident][k]
obj = Local()
# obj2=Local()  #谢谢对象用的都是同一个字典
# obj3=Local()
# obj4=Local()
# obj5=Local()
def task(arg):
    obj.val = arg
    time.sleep(1)
    print(obj.val)
for i in range(10):
    t = Thread(target=task,args=(i,))
    t.start()
上面那个用的全是类的字典,不管生成几个对象,用的都是同一个,也有可能造成数据错乱
所以我们希望每次生成local对象用的都是自己的字典,所以对上面的继续改进2
改进版2
from
threading import get_ident,Thread import time class Local(object): def __init__(self): #将字典放在init中,这样每个对象用的都是自己的字典,但是要注意黄色部分的写法会出现一直递归,报错, object.__setattr__(self,'storage',{}) #这里直接调用父类的__setattr__方法 #这样写会出现递归,该出调用__setattr__,se # self.storage={} def __setattr__(self, k, v): ident = get_ident() if ident in self.storage: self.storage[ident][k] = v else: self.storage[ident] = {k: v} def __getattr__(self, k): ident = get_ident() return self.storage[ident][k] obj = Local() def task(arg): obj.val = arg # obj.xxx = arg time.sleep(1) print(obj.val) for i in range(10): t = Thread(target=task,args=(i,)) t.start() 到此为止,自己写了一个local对象,只支持线程
#改进版3即支持协程又支持线程
try:
    #getcurrent 获取协程id
    from greenlet import getcurrent as get_ident
except Exception as e:
    from threading import get_ident
from 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] = v
        else:
            self.storage[ident] = {k: v}
    def __getattr__(self, k):
        ident = get_ident()
        return self.storage[ident][k]
obj = Local()
def task(arg):
    obj.val = arg
    obj.xxx = arg
    print(obj.val)
for i in range(10):
    t = Thread(target=task,args=(i,))
    t.start()

 

Guess you like

Origin www.cnblogs.com/Hale-wang/p/11209795.html