Python实例变量是否是线程安全的?

Sha*_*ane 20 python multithreading thread-safety

好的,首先检查以下代码:

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()
Run Code Online (Sandbox Code Playgroud)

我面临着和上面相同的情况.我真的想知道它是否是线程安全的self.Counter,如果没有,我有什么选择?我只能想到threading.RLock()锁定这个资源,还有什么好主意?

aay*_*ubi 32

您可以使用锁,RLocks,信号量,条件,事件和队列.
这篇文章给了我很多帮助.
看看:Laurent Luce的博客

  • 什么,没有自旋锁!?:p (2认同)

Aar*_*lla 25

使用实例字段self.Counter线程安全的或"原子的".阅读,或指定一个值-即使它需要在内存中4个字节,你将永远不会得到一个半改变值.但是操作self.Counter = self.Counter + 1不是因为它读取值然后写入它 - 另一个线程可以在读取之后和写回之前更改字段的值.

所以你需要用锁来保护整个操作.

由于方法体基本上是整个操作,因此可以使用装饰器来完成此操作.请参阅此答案以获取示例:https://stackoverflow.com/a/490090/34088

  • @EliBendersky:我猜他的意思是像`self.Counter = Value`这样的操作是线程安全的.查看我刚发现的这篇文章:http://effbot.org/pyfaq/what-kinds-of-global-value-mutation-are-thread-safe.htm (3认同)
  • 我所说的是***赋值是原子的(64位类型除外).请参见http://stackoverflow.com/questions/4756536/what-operations-in-java-are-considered-atomic (3认同)

Eli*_*sky 10

不,它不是线程安全的 - 两个线程实际上是同时修改同一个变量.是的,解决方案是threading模块中的锁定机制之一.

BTW,self.Counter是一个实例变量,不是类变量.