欢迎来到Louis的博客

人生三从境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 衣带渐宽终不悔,为伊消得人憔悴。 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。
扩大
缩小

python 多线程 threading.local

threading.local 是一个全局变量,作用在线程(主线程和子线程适用)中,目的是在每个线程中私有一份空间存放自己私有的变量。

用法:

import threading
import time
from concurrent.futures import ThreadPoolExecutor

v = threading.local()
lock = threading.RLock()

def func(arg):
    v.phone = arg
    time.sleep(2)
    lock.acquire()
    print(arg, v.phone)
    lock.release()

p = ThreadPoolExecutor(3)


for i in range(30):
    p.submit(func, i)

以上代码的每个线程中都有一个v.phone且值都是隔离独立的。

 

模拟实现:

import threading
import time

class Local(object):
    info = {}
    def __getattr__(self, item):
        ident = threading.get_ident()
        return self.info[ident][item]

    def __setattr__(self, key, value):
        ident = threading.get_ident()
        if ident in self.info:
            self.info[ident][key] = value
        else:
            self.info[ident] = {key:value}

obj = Local()
lock = threading.RLock()



def func(args):
    obj.num1 = args     # 子进程设置私有变量
    time.sleep(2)
    t_name = threading.current_thread().getName()
    lock.acquire()
    print('线程%s的num1:'%t_name, obj.num1)
    lock.release()


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


obj.num1 = 100  # 主线程设置自己的私有变量

print('主线程的num1:', obj.num1)

上面代码中定义的类在实例化时,创建了一个字典,当在线程中使用obj.num1 = arg进行赋值时,会调用对象的__setattr__方法,将线程的id作为key,num:key的键值对作为value来填充这个字典,而使用obj.num1获取值时则是调用对象的__getattr__方法,会获取当前线程的id,然后通过id找到对应的子字典,在子字典中通过key num1找到对应的值。

 

posted on 2018-09-11 17:53  Louiszj  阅读(384)  评论(0编辑  收藏  举报

导航