当使用当前线程的线程ID只读取或写入时,Python字典线程是否安全? 喜欢
import thread import threading class Thread(threading.Thread): def __init__(self, data): super(Thread, self).__init__() self.data = data def run(self): data = self.data[thread.get_ident()] # ...Is a Python dictionary thread safe when using the thread ID of the current thread only to read or write? Like
import thread import threading class Thread(threading.Thread): def __init__(self, data): super(Thread, self).__init__() self.data = data def run(self): data = self.data[thread.get_ident()] # ...最满意答案
如果 data是标准Python字典,则__getitem__调用完全在C中实现,而对于thread.get_ident()返回的整数值的__hash__方法也是thread.get_ident() 。 此时, data.__getitem__(<thread identifier>)调用是线程安全的。 这同样适用于写入data ; data.__setitem__()调用完全用C语言处理。
在Python代码中实现任何这些钩子的时刻,GIL可以在字节码之间释放,所有的赌注都关闭。
这一切都假设您正在使用CPython; Jython,IronPython,PyPy和其他python实现可能会在何时切换线程时做出不同的决定。
您最好使用threading.local()映射对象,因为这可以保证为您提供线程本地命名空间。 它只支持属性访问。
If data is a standard Python dictionary, the __getitem__ call is implemented entirely in C, as is the __hash__ method on the integer value returned by thread.get_ident(). At that point the data.__getitem__(<thread identifier>) call is thread safe. The same applies to writing to data; the data.__setitem__() call is entirely handled in C.
The moment any of these hooks are implemented in Python code, the GIL can be released between bytecodes and all bets are off.
This all makes the assumption you are using CPython; Jython, IronPython, PyPy and other python implementations may make different decisions on when to switch threads.
You'd be better of using the threading.local() mapping object instead, as that is guaranteed to provide you with a thread-local namespace. It only supports attribute access though.
更多推荐
发布评论