首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python线程安全锁循环

python线程安全锁循环
EN

Stack Overflow用户
提问于 2012-10-24 13:17:45
回答 2查看 1.3K关注 0票数 0

请有人告诉我,以下是否是线程安全,如果不是,我必须做什么才能做到这一点。

注意:这只是一个小样本,不确定它是否运行。

代码语言:javascript
复制
TIMER = True
time_lock = threading.Lock()
def timing():
    while TIMER:
        # some logic will be here for now print time
        print time.time()

timer = threading.Thread(target=timing)
timer2 = threading.Thread(target=timing)
timer.start()
timer2.start()

while True:
    time_lock.aquire()
    if doSomeStuff():
        TIMER = True
    if otherThings():
        break
    time_lock.aquire()
    TIMER = False
    time_lock.release()

time_lock.aquire()
TIMER = False
time_lock.release()
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-10-24 18:08:41

这在一定程度上取决于您正在使用的实现以及您正在做什么。

首先,在python的实际标准实现("cpython")中,一次只允许运行一个线程,因为python解释器的一些内部元素并不是线程安全的。这是由Global解释器锁(又名"GIL")控制的。因此,在cpython中,根本不需要额外的锁;GIL确保一次只运行一个线程,运行python代码,并可能更改变量。这是实现的一个特点,而不是语言的特点。

第二,如果只有一个线程写入一个简单变量,而其他线程只读取它,那么出于显而易见的原因,您也不需要锁。然而,这取决于您作为程序员,以确保这是事实,这是很容易犯错误的。

即使是简单的变量,也可能不需要锁。在python中,变量更像是用于引用对象的标签,而不是可以放入的框。因此,简单的赋值是原子的(在某种意义上,它们不能中途中断),在查看生成的python字节码时可以看到:

代码语言:javascript
复制
In [1]: import dis

In [2]: x = 7

In [3]: def setx():
    global x
    x = 12
   ...:     

In [4]: dis.dis(setx)
  3           0 LOAD_CONST               1 (12)
              3 STORE_GLOBAL             0 (x)
              6 LOAD_CONST               0 (None)
              9 RETURN_VALUE        

唯一更改x的代码是单个STORE_GLOBAL操作码。因此,变量要么改变了,要么没有变化;之间没有不一致的状态。

但是,如果您想测试某个变量的某个值,并在测试仍然有效的情况下执行一个操作,那么您确实需要一个锁。因为另一个线程可以在测试之后更改变量。

像附加到列表或交换变量这样的事情并不是原子的。但在cpython中,这些都会受到GIL的保护。在其他实现中,您需要对这些操作设置一个锁,以防止可能的不一致。

票数 2
EN

Stack Overflow用户

发布于 2012-10-24 13:23:24

如果我正确地理解了你,你想在什么时候停止提示你的线程。因为在这种情况下,只有一个线程写入共享变量,并且只写一次,所以不需要锁。

当您对无法原子读取的共享数据结构进行并发修改时,锁是必需的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13050061

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档