• Threading.local


    作用

    为每个线程创建一个独立的空间,使得线程对自己的空间中的数据进行操作(数据隔离)。

    import threading
    from threading import local
    import time
    
    obj = local()
    
    
    def task(i):
    	obj.xxxxx = i
    	time.sleep(2)
    	print(obj.xxxxx,i)
    
    for i in range(10):  #开启了10个线程
    	t = threading.Thread(target=task,args=(i,))
    	t.start()
    

    如何获取一个线程的唯一标记? 

    线程:threading.get_ident()

    协程:greenlet.getcurrent()

    根据字典自定义一个类似于threading.local功能?

    import time
    import threading
    
    DIC = {}
    
    def task(i):
    	ident = threading.get_ident()
    	if ident in DIC:
    		DIC[ident]['xxxxx'] = i
    	else:
    		DIC[ident] = {'xxxxx':i }
    	time.sleep(2)
    
    	print(DIC[ident]['xxxxx'],i)
    
    for i in range(10):   #开启了10个线程
    	t = threading.Thread(target=task,args=(i,))
    	t.start()
    

    根据字典自定义一个为每个协程开辟空间进行存取数据。

    import time
    import threading
    import greenlet
    
    DIC = {}
    
    def task(i):
    	
    	# ident = threading.get_ident()
    	ident = greenlet.getcurrent()
    	if ident in DIC:
    		DIC[ident]['xxxxx'] = i
    	else:
    		DIC[ident] = {'xxxxx':i }
    	time.sleep(2)
    
    	print(DIC[ident]['xxxxx'],i)
    
    for i in range(10):   #开启了10个线程
    	t = threading.Thread(target=task,args=(i,))
    	t.start()
    

    通过getattr/setattr 构造出来 threading.local的加强版(协程)

    import time
    import threading
    try:
    	import greenlet
    	get_ident =  greenlet.getcurrent   #协程    get_ident相当于全局变量
    except Exception as e:
    	get_ident = threading.get_ident    #线程
      
    class Local(object):
    	DIC = {}
    
    	def __getattr__(self, item):
    		ident = get_ident()
    		if ident in self.DIC:
    			return self.DIC[ident].get(item)
    		return None
    
    	def __setattr__(self, key, value):
    		ident = get_ident()
    		if ident in self.DIC:
    			self.DIC[ident][key] = value
    		else:
    			self.DIC[ident] = {key:value}
    		
    
    obj = Local()
    
    def task(i):
    	obj.xxxxx = i
    	time.sleep(2)
    	print(obj.xxxxx,i)
    
    for i in range(10):       #开启了10个线程
    	t = threading.Thread(target=task,args=(i,))
    	t.start()
    

    为什么要做数据隔离?

    每个人请求需要做数据隔离,不然会出现数据混乱。每个请求数据不同,需要放在不同的空间,根据线程不同,取不同的值。

    真正请求来了之后,会通过local对象为他创造一块空间,每个请求来都会做个数据隔离

  • 相关阅读:
    JavaScript的语法、数据类型、基本算数和逻辑运算操作
    ES6之常用开发知识点:入门(一)
    ES6中map数据结构
    VUE路径问题

    JS简易计算器的实现,以及代码的优化
    格雷编码
    H5网页布局+css代码美化
    jQuery---五角星评分案例
    Ajax工作原理及优缺点
  • 原文地址:https://www.cnblogs.com/gaoya666/p/9180421.html
Copyright © 2020-2023  润新知