簡體   English   中英

Python 實例變量是線程安全的嗎?

[英]Are Python instance variables thread-safe?

OK,先檢查以下代碼:

class DemoClass():

    def __init__(self):
        #### I really want to know if self.Counter is thread-safe. 
        self.Counter = 0

    def Increase(self):
        self.Counter = self.Counter + 1

    def Decrease(self):
        self.Counter = self.Counter - 1

    def DoThis(self):
        while True:
            Do something

            if A happens:
                self.Increase()
            else:
                self.Decrease()

            time.sleep(randomSecs)

    def DoThat(self):
        while True:
            Do other things

            if B happens:
                self.Increase()
            else:
                self.Decrease()

            time.sleep(randomSecs)

    def ThreadSafeOrNot(self):
        InterestingThreadA = threading.Thread(target = self.DoThis, args = ())
        InterestingThreadA.start()

        InterestingThreadB = threading.Thread(target = self.DoThat, args = ())
        InterestingThreadB.start()

我面臨與上述相同的情況。 我真的很想知道self.Counter是否線程安全,如果不是,我有什么選擇? 我只能想到threading.RLock()來鎖定這個資源,有什么更好的主意嗎?

您可以使用鎖,RLocks,信號量,條件,事件和隊列。
這篇文章給了我很多幫助。
看看: Laurent Luce的博客

使用實例字段self.Counter線程安全的或“原子的” 閱讀,或分配一個值-即使它需要在內存中4個字節,你將永遠不會得到一個半改變值。 但是操作self.Counter = self.Counter + 1不是因為它讀取值然后寫入它 - 另一個線程可以在讀取之后和寫回之前更改字段的值。

所以你需要用鎖來保護整個操作。

由於方法體基本上是整個操作,因此可以使用裝飾器來完成此操作。 請參閱此答案以獲取示例: https//stackoverflow.com/a/490090/34088

不,它不是線程安全的 - 兩個線程實際上是同時修改同一個變量。 是的,解決方案是threading模塊中的鎖定機制之一。

順便說一句, self.Counter是一個實例變量 ,而不是類變量

self.Counter是一個實例變量,因此每個線程都有一個副本。

如果在__init__()之外聲明變量,它將是一個類變量。 該類的所有實例都將共享該實例。

Atomos庫為 Python 原語和對象(包括原子計數器)提供原子(線程安全)包裝器。 它使用單寫者/多讀者鎖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM