Python线程安全的对象
概述
多线程安全的对象。 threading.local
import threading
# 线程安全
l = threading.local()
def func(*args):
l.x = args[0]
# id(l) 所有线程是相等的,是用一个对象。
print id(l)
# id(l.x) 这个对象的地址都是不同的。
print id(l.x)
ts = []
for x in xrange(4):
ts.append(threading.Thread(target=func, args=(x,)))
for t in ts:
t.join()
l的地址是一样的,但是l.x的地址是不一样的说明l.__setattr__和__getattr__是特殊的。
实现类似于
try:
from greenlet import getcurrent as get_ident
except ImportError:
try:
from thread import get_ident
except ImportError:
from _thread import get_ident
class Local(object):
__slots__ = ('__storage__', '__ident_func__')
def __init__(self):
object.__setattr__(self, '__storage__', {})
object.__setattr__(self, '__ident_func__', get_ident)
def __getattr__(self, name):
try:
# 在这里我们返回调用了self.__ident_func__(),也就是当前的唯一ID
# 来作为__storage__的key
return self.__storage__[self.__ident_func__()][name]
except KeyError:
raise AttributeError(name)
def __setattr__(self, name, value):
ident = self.__ident_func__()
storage = self.__storage__
try:
storage[ident][name] = value
except KeyError:
storage[ident] = {name: value}
get_ident会取得每个线程号,而且线程号都是唯一的,因此sotrage[ident]就实现了线程隔离。