假设我使用signal
处理程序来处理间隔计时器。
def _aHandler(signum, _):
global SomeGlobalVariable
SomeGlobalVariable=True
我是否可以设置SomeGlobalVariable
而不必担心,在设置SomeGlobalVariable
(即Python VM正在执行字节码来设置变量)时,信号处理程序中的赋值会中断某些内容?(即亚稳态状态)
更新:我特别感兴趣的是在处理程序之外进行“复合赋值”的情况。
(也许我觉得太“低级”了,这一切都是在Python中处理的。。。来自嵌入式系统的背景,我不时会有这样的冲动)
谷歌的风格指南建议不要这样做
我并不是说Google样式指南是终极真理,但是rationale in the "Threading" section提供了一些见解(highlight是我的):
所以我的解释是,在Python中,一切都像dict一样,当你在后端做
a = b
时,globals['a'] = b
就会发生,这很糟糕,因为dict不一定是线程安全的。但是对于单个变量,
Queue
并不理想,因为我们希望它只包含一个元素,而且我在stdlib中找不到一个完美的预先存在的容器来自动同步一个.set()
方法。所以现在我只想:有趣的是Martelli does not seem to mind谷歌风格的指南推荐:-)(他在谷歌工作)
我想知道CPython GIL是否对这个问题有影响:What is the global interpreter lock (GIL) in CPython?
这个线程还表明CPython dict是线程安全的,包括下面的词汇表引用,它明确提到了CPython dict https://docs.python.org/3/glossary.html#term-global-interpreter-lock
复合赋值包括三个步骤:读-更新-写。如果运行另一个线程并在读取后写入新值,但在写入前写入,则这是竞争条件。在这种情况下,一个过时的值将被更新并写回,这将删除其他线程写入的任何新值。在Python中,任何涉及单字节代码执行的内容都应该是原子的,但是复合赋值不符合这个条件。用锁。
简单变量的简单赋值是“原子”的,也就是线程安全的(复合赋值,比如
+=
,或者对象的项或属性的赋值不一定是原子的,但是您的示例是一个简单的,尽管是全局的,变量的简单赋值,因此是安全的)。相关问题 更多 >
编程相关推荐