代码之家  ›  专栏  ›  技术社区  ›  Phong

python内置容器是线程安全的吗?

  •  44
  • Phong  · 技术社区  · 15 年前

    我想知道python内置容器(list、vector、set…)是否是线程安全的?还是需要为共享变量实现一个锁定/解锁环境?

    3 回复  |  直到 10 年前
        1
  •  43
  •   tshepang Arrie    10 年前

    您需要为将在Python中修改的所有共享变量实现自己的锁定。您不必担心从不会被修改的变量中读取(即,并发读取是可以的),因此不可变类型( frozenset , tuple , str 可能 安全,但不会受伤。为了你将要改变的事情- list , set , dict 以及大多数其他对象,您应该有自己的锁定机制(虽然在这些对象上就地操作正常,但线程可能会导致非常讨厌的错误——您也可以实现锁定,这非常容易)。

    顺便说一下,我不知道您是否知道这一点,但是在Python中锁定非常容易——创建一个threading.lock对象,然后您可以这样获取/释放它:

    import threading
    list1Lock = threading.Lock()
    
    with list1Lock:
        # change or read from the list here
    # continue doing other stuff (the lock is released when you leave the with block)
    

    在python 2.5中,do from __future__ import with_statement ;python 2.4及之前版本没有此功能,因此您需要将acquire()/release()调用放入 try:...finally: 阻碍:

    import threading
    list1Lock = threading.Lock()
    
    try:
        list1Lock.acquire()
        # change or read from the list here
    finally:
        list1Lock.release()
    # continue doing other stuff (the lock is released when you leave the with block)
    

    Some very good information about thread synchronization in Python .

        2
  •  8
  •   John La Rooy    15 年前

    是的,但你还是需要小心,当然

    例如:

    如果有两条线 pop() 从只有一个项目的列表中,一个线程将成功获取该项目,另一个线程将获得 IndexError

    这样的代码不是线程安全的

    if L:
        item=L.pop() # L might be empty by the time this line gets executed
    

    你应该这样写

    try:
        item=L.pop()
    except IndexError:
        # No items left
    
        3
  •  4
  •   Ignacio Vazquez-Abrams    15 年前

    只要不禁用线程的C代码中的gil,它们就是线程安全的。