gpt4 book ai didi

python - getattr/setattr/hasattr/delattr 线程安全吗?

转载 作者:太空宇宙 更新时间:2023-11-03 14:28:04 27 4
gpt4 key购买 nike

看这个单例实现:

if not hasattr(Singleton, "_instance"):                                    
with Singleton._instance_lock:
if not hasattr(Singleton, "_instance"):
Singleton._instance = Singleton()
return Singleton._instance

似乎“Singleton._instance = ..”(类似于setattr)和hasattr 是原子的。或者 hasattr 不会因为 setattr 而导致崩溃。

但我找不到任何支持以上“似乎”的东西。

最佳答案

通常,前提是您对其调用操作的对象未实现 __getattr__ , __delattr____setattr__ hooks in python,那么是的,hasattr, getattr, delattr and setattr 都是原子操作。

就 Python 线程而言,任何单独的字节码都是原子操作。 Python 评估循环在解释操作码时获取全局解释器锁 (GIL)。

您需要查看字节码以了解边界所在:

>>> def foo():
... if not hasattr(Singleton, "_instance"):
... with Singleton._instance_lock:
... if not hasattr(Singleton, "_instance"):
... Singleton._instance = Singleton()
... return Singleton._instance
...
>>> dis.dis(foo)
2 0 LOAD_GLOBAL 0 (hasattr)
3 LOAD_GLOBAL 1 (Singleton)
6 LOAD_CONST 1 ('_instance')
9 CALL_FUNCTION 2
12 POP_JUMP_IF_TRUE 64

3 15 LOAD_GLOBAL 1 (Singleton)
18 LOAD_ATTR 2 (_instance_lock)
21 SETUP_WITH 35 (to 59)
24 POP_TOP

4 25 LOAD_GLOBAL 0 (hasattr)
28 LOAD_GLOBAL 1 (Singleton)
31 LOAD_CONST 1 ('_instance')
34 CALL_FUNCTION 2
37 POP_JUMP_IF_TRUE 55

5 40 LOAD_GLOBAL 1 (Singleton)
43 CALL_FUNCTION 0
46 LOAD_GLOBAL 1 (Singleton)
49 STORE_ATTR 3 (_instance)
52 JUMP_FORWARD 0 (to 55)
>> 55 POP_BLOCK
56 LOAD_CONST 0 (None)
>> 59 WITH_CLEANUP
60 END_FINALLY
61 JUMP_FORWARD 0 (to 64)

6 >> 64 LOAD_GLOBAL 1 (Singleton)
67 LOAD_ATTR 3 (_instance)
70 RETURN_VALUE

故事并没有就此结束; hasattr 使用 getattr()(测试异常),后者又可以调用 Python __getattr__ Hook 。同样,STORE_ATTR 操作码最终可能会调用 python __setattr__ Hook 实现。在这两种情况下,GIL 都会被再次释放。

对于默认实现(Singleton 不实现这些钩子(Hook)),操作是原子的,因为 Python C 代码处理整个操作而不会回退到 Python,因此评估循环(GIL 可能被释放)并再次锁定另一个线程)。

当然,您仍然可以处理在 object protocol operations 期间释放锁的自定义 C 库.那将是一件不寻常的事情。

关于python - getattr/setattr/hasattr/delattr 线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16872210/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com