【问题标题】:Python boolean thread safePython 布尔线程安全
【发布时间】:2021-10-18 13:48:41
【问题描述】:

如果我使用布尔值来控制线程的循环,如果我在检查它的值之前没有锁定它,可能会发生什么。可以引发异常吗?

请注意,如果我的循环再次运行,这不是问题,但如果可能的话,我想避免锁定资源的成本

# self is the same object in the 2 functions

def __init__(self):
    self.status=True

# thread 1
def stop(self):
    # Lock acquired to avoid concurrent writes
    self.lock.acquire()
    self.status=False
    self.lock.release()

# thread 2
def thread_func(self):
    while self.status:
      # Do stuff
      # Not important if it does a cycle more after status is set to false

【问题讨论】:

  • 这能回答你的问题吗? Is Python variable assignment atomic?
  • @mkrieger1 我需要对此进行一些澄清,因为该帖子的第二个答案。我这边的问题是阅读是否会导致异常。它是来自内存的简单加载,因此它不会发生吗?或者尝试加载正在写入的内存区域可以提高它?

标签: python python-3.x


【解决方案1】:

无需锁定。 Python 使用 GIL(全局解释器锁)来防止同时从不同线程访问对象。

在 CPython 中,全局解释器锁或 GIL 是一个互斥锁, 保护对 Python 对象的访问,防止多个线程 一次执行 Python 字节码。 GIL 防止竞争条件 并确保线程安全 [https://wiki.python.org/moin/GlobalInterpreterLock]

当您想在涉及多个字节码的操作期间阻止对某些对象的访问时,应使用锁定,例如,如果您有多个线程执行此操作:

x.data1 = 10
x.data2 = 20
x.process()

如果线程在第一行和第二行之间切换,您最终可能会使用混合数据调用 x.process(),或者可能会使用相同的数据调用两次 x.process()

在这种情况下,您应该使用锁。

一般来说,当您涉及读取和写入的相关原子操作不止一个时,就会出现问题。

注意单

x += 1

不是原子的,python 可以在读取 x 之后但在重新分配它之前切换线程。因此,如果该行有多个线程,则应使用锁,否则将出现不可预知的行为。 (x 的值可能比您预期的要小)

【讨论】:

    猜你喜欢
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 2014-08-29
    • 2021-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多