8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

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

user3369908 2月前

83 0

好的,首先检查以下代码:class DemoClass(): def __init__(self): #### 我真的想知道 self.Counter 是否是线程安全的。 self.Counter = 0 def Increase(self): ...

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

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() 锁定此资源,有什么更好的主意吗?

帖子版权声明 1、本帖标题:Python 实例变量是线程安全的吗?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由user3369908在本站《multithreading》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 多个线程同时访问变量会导致竞争条件和不良行为。您必须依赖锁、RLock、信号量、条件、事件或队列。

    以下 文章 有助于理解它们之间的区别以及何时在多线程环境中使用它们:

  • 使用实例字段 self.Counter 线程安全的或“原子的” 或此处 )。读取它或分配 一个 值 - 即使它需要 4 个字节的内存,您也永远不会得到半更改的值。但操作 self.Counter = self.Counter + 1 不是,因为它读取该值然后写入它 - 另一个线程可以在读取之后和写回之前更改字段的值。

    所以您需要用锁来保护整个操作。

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

  • @EliBendersky:我猜他的意思是像 self.Counter = Value 这样的操作是线程安全的。查看我刚刚找到的这篇文章:effbot.org/pyfaq/…

  • 赋值不是线程安全的。假设您有 self.Counter=1,然后是 self.Counter=2,然后 x=self.Counter。然后 x 可以根据线程切换获得 1 或 2,这使得赋值不是线程安全的。

  • 我说的是,单个赋值是原子的(64 位类型除外)。请参阅 .com/questions/4756536/…

  • 由于类的实例变量仅存在于一个线程中,因此增量如何成为一个问题。实例变量是否跨线程共享?

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

    顺便说一句, self.Counter 是一个 实例变量 ,而不是 类变量 .

  • 我认为只有类变量不是线程安全的。实例变量应该是线程安全的,除非类实例是全局创建的,并传递给线程。你怎么看?

  • 引用 10

    @variable 因为实例可以传递到不同的线程,所以你的观点没有意义。无论实现方式如何,事物都是线程安全的,或者不是线程安全的。

  • self.Counter 是一个实例变量,因此每个线程都有一个副本。

    如果在 之外声明变量 __init__() ,它将是一个类变量。该类的所有实例都将共享该实例。

  • @HarryJohnston 对此要非常小心。这可能会增加相当多的复杂性。您可能必须进行某种形式的锁定。

  • @AustinHenley:是的,这就是重点。原帖作者想知道实例变量是否是线程安全的。

  • Ton 2月前 0 只看Ta
    引用 14

    我认为只有类变量不是线程安全的。实例变量应该是线程安全的,除非类实例是全局创建的,并传递给线程。你怎么看?

  • 对象 Atomos 提供原子(线程安全)包装器,包括原子计数器。它使用单写入器/多读取器锁。

返回
作者最近主题: