亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

getattr / setattr / hasattr / delattr線程安全嗎?

getattr / setattr / hasattr / delattr線程安全嗎?

元芳怎么了 2021-03-16 17:33:10
查看此Singleton實現: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而導致崩潰。但是我找不到任何可以支持上述“似乎”的東西。
查看完整描述

1 回答

?
慕的地8271018

TA貢獻1796條經驗 獲得超4個贊

通常,只要你呼吁行動沒有實現目標__getattr__,__delattr__或者__setattr__在python掛鉤,那么是的,hasattr,getattr,delattr和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__鉤子。同樣,STORE_ATTR操作碼最終可能會調用python__setattr__鉤子實現。在這兩種情況下,GIL都會再次被釋放。


對于默認實現(Singleton不實現這些掛鉤),操作是原子性的,因為Python C代碼可處理整個操作而不會退回到Python上,因此會產生評估循環(可能釋放GIL并再次鎖定另一個線程)。


當然,您仍然可以使用自定義C庫,該C庫在對象協議操作期間釋放鎖。那將是不尋常的事情。


查看完整回答
反對 回復 2021-03-29
  • 1 回答
  • 0 關注
  • 181 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號