本站消息

  本站每日ip已达10000,出租广告位,位置价格可谈,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2019-03(1)

2019-04(1)

2019-05(2)

2019-06(2)

2019-07(5)

并发编程(2)----threading.local()剖析

发布于2020-03-31 14:45     阅读(1062)     评论(0)     点赞(20)     收藏(5)


threading.loacl()对象内部实质上是一个字典

我们都知道通过threading.local()可以创建一个独立可靠的为线程存取数据空间,但内部到底是怎样的,我们来分析一下

1.为什么要有threading.local()

threading.local()的作用和线程锁是一样的,为了保护线程安全。threading.local()为每个线程提供可靠的数据存取空间,保证每个线程数据的安全与独立。

1.简单分析

import threading
import time

info = {}
def test(arg):
    tid = threading.get_ident()   #获取线程的id
    info[tid] = arg    #根据线程的id添加值(id是唯一的)
    time.sleep(2)
    print(info[tid],arg) 

for i in range(10):
    t = threading.Thread(target=test,args=(i,))
    t.start()

首先我们创建一个字典对象用来放各个线程的数据,根据线程id是唯一的这个原理,我们将线程id作为键,线程中的数据作为值,保存到字典对象中

2.进阶分析

import threading
import time
INFO = {}
class Local(object):
    def __getattr__(self,key):
        tid = threading.get_ident()
        return INFO[tid][key]

    def __setattr__(self, key, value):
        tid = threading.get_ident()
        if tid in INFO:  #存在该线程的空间
            INFO[tid][key] = value
        else: #不存在该线程的空间
            INFO[tid] = {key:value}  #给该线程创建空间并存入数据

v = Local()

def poop(arg):
    v.phone = arg   #调用对象的__setattr__方法
    time.sleep(2)
    print(v.phone,arg)   #调用对象的__getattr__方法

for i in range(10):
    t = threading.Thread(target=poop,args=(i,))
    t.start()

我们不妨创建自己的Local对象,数据还是存在字典中,还是将线程的id作为标识,当我们给对象赋值时就调用了__setattr__方法,当我们从对象中取值时调用了__getattr__方法,通过这两个方法我们可以实现自由的存取数据,而且保证不同的线程之间数据是独立的。

总结:核心就是用字典来存储数据,通过线程id的唯一性来确定唯一的字典对象来存取数据



所属网站分类: 技术文章 > 博客

作者:精灵

链接: https://www.pythonheidong.com/blog/article/292466/

来源: python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

20 0
收藏该文
已收藏

评论内容:(最多支持255个字符)