今天碰到跟_threading_local有关的问题,居然查不到太多信息,就自己翻译一下吧。
_threading_local
index
/usr/local/lib/python2.4/_threading_local.py
Module Docs
Thread-local 对象
(这个模块提供了threading.local类的Python版本,根据使用的Python版本的不同,可能会有更快的版本。你应该总是从threading里import local类。)
Thread-local对象提供对thread-local数据的管理。
如果你有需要对线程来讲是局部的数据,只需创建一个thread-local对象,像这样使用其属性:
>>> mydata = local()
>>> mydata.number = 42
>>> mydata.number
42
你也可以访问local对象的字典:
>>> mydata.__dict__
{'number': 42}
>>> mydata.__dict__.setdefault('widgets', [])
[]
>>> mydata.widgets
[]
关于thread-local对象最重要的就是它的数据对线程是局部的。如果我们像这样在不同的线程里访问该数据:
>>> log = []
>>> def f():
... items = mydata.__dict__.items()
... items.sort()
... log.append(items)
... mydata.number = 11
... log.append(mydata.number)
>>> import threading
>>> thread = threading.Thread(target=f)
>>> thread.start()
>>> thread.join()
>>> log
[[], 11]
我们将得到不同的数据。进一步,在另一个线程里对数据的更改不会影响到当前线程里的数据:
>>> mydata.number
42
当然,你从一个local对象得到的值,包括__dict__属性,对任一个线程来说都是当前最新的。因此,你通常都不会想在线程之间为这些值,因为它们只属于被定义的那个线程。
你可以通过继承local类来自定义一个local对象:
>>> class MyLocal(local):
... number = 2
... initialized = False
... def __init__(self, **kw):
... if self.initialized:
... raise SystemError('__init__ called too many times')
... self.initialized = True
... self.__dict__.update(kw)
... def squared(self):
... return self.number ** 2
这样可以支持不同的值、方法和构造函数。注意如果你定义了__init__方法,它会在local对象在不同的线程被使用的时候被调用。这在需要初始化每个线程的字典的时候有用。
现在我们来创建一个local对象:
>>> mydata = MyLocal(color='red')
我们有了不同的number:
>>> mydata.number
2
一个初始化了的color:
>>> mydata.color
'red'
>>> del mydata.color
还有一个处理数据的方法:
>>> mydata.squared()
4
跟以前一样,我们可以在另一个线程里访问数据:
>>> log = []
>>> thread = threading.Thread(target=f)
>>> thread.start()
>>> thread.join()
>>> log
[[('color', 'red'), ('initialized', True)], 11]
当前线程的数据不受影响:
>>> mydata.number
2
>>> mydata.color
Traceback (most recent call last):
...
AttributeError: 'MyLocal' object has no attribute 'color'
子类可以定义slot,但是这不是线程局部的。它们在线程之间是共享的:
>>> class MyLocal(local):
... __slots__ = 'number'
>>> mydata = MyLocal()
>>> mydata.number = 42
>>> mydata.color = 'red'
因此,另一个线程:
>>> thread = threading.Thread(target=f)
>>> thread.start()
>>> thread.join()
会影响到当前线程:
>>> mydata.number
11
>>> del mydata