threading.local和高级

threading.local特点:

①为每个线程开辟空间,让你进行存取值(根据线程ID来固定某个值)

②flask中没有threading.local,但是flask中的上下文管理的思想是借鉴的threading.local.

③在线程关闭之前值保持不变,线程关闭后值就清空了.

普通多线程

import time
import threading


class Foo(object):
        def __init__(self):
                self.num = 0

val2 = Foo()

def task(i):
        val2.num = i
        time.sleep(1)
        print(val2.num)

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

结果:
3
3
3
3
4个值全一样

threading.local多线程

import time
import threading
# 当每个线程在执行 val1.xx=1 ,在内部会为此线程开辟一个空间,来存储 xx=1
# val1.xx,找到此线程自己的内存地址去取自己存储 xx
val1 = threading.local()

def task(i):
        val1.num = i
        time.sleep(1)
        print(val1.num)

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

输出结果:
0
1
2
3
四个结果不同

自定义threading.local

import threading
"""
storage = {            #自定义的维护一个这样的字典
1111:{'x1':0},
1112:{'x1':1}
1113:{'x1':2}
1114:{'x1':3}
1115:{'x1':4}
}
"""
class Local(object):
        def __init__(self):
                object.__setattr__(self,'storage',{})

        def __setattr__(self, key, value):
                ident = threading.get_ident()     #这个就是线程id
                if ident in self.storage:
                        self.storage[ident][key] = value
                else:
                        self.storage[ident] = {key:value}

        def __getattr__(self, item):
                ident = threading.get_ident()     #这个就是线程id
                if ident not in self.storage:
                        return
                return self.storage[ident].get(item)

local = Local()

def task(arg):
        local.x1 = arg
        print(local.x1)

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

输出:
0
1
2
3
4

会根据你不同的线程ID来输出不同的值

 加强版自定义threading.local(flask的上下文管理就这样)

原来维护的是一个字典里面还是字典:
"""
storage = {
1111:{'x1':0},
1112:{'x1':1}
1113:{'x1':2}
1114:{'x1':3}
1115:{'x1':4}
}
"""
加强版维护的是一个字典里面是字典加列表:
"""
storage = {
1111:{'x1':[0,1]},
1112:{'x1':[0,1,2]}
1113:{'x1':[0,1,3]}
1114:{'x1':[0,1,5]}
1115:{'x1':[0,1,6]}
}
"""
这个维护的列表要当做栈(append往里加,如果是取值就用[-1],要是拿走值就用pop)来使用,后进先出

import threading
"""
storage = {
1111:{'x1':[]},
1112:{'x1':[]}
1113:{'x1':[]}
1114:{'x1':[]}
1115:{'x1':[]},
1116:{'x1':[]}
}
"""
class Local(object):
        def __init__(self):
                object.__setattr__(self,'storage',{})

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

        def __getattr__(self, item):
                ident = threading.get_ident()
                if ident not in self.storage:
                        return
                return self.storage[ident][item][-1]

local = Local()

def task(arg):
        local.x1 = arg
        print(local.x1)

for i in range(5):
        t = threading.Thread(target=task,args=(i,))
        t.start()
输出:
0
1
2
3
4

猜你喜欢

转载自www.cnblogs.com/shengjunqiye/p/11923729.html