Как я могу использовать GIL для словаря в многопоточном приложении?

Я столкнулся с ошибкой 'RuntimeError: словарь изменил размер во время итерации' при итерации по словарю в потоке, который вставляется в другой поток в Python 2.7. Я обнаружил, что с помощью Global Intrepreter Lock мы можем заблокировать объект в многопоточной ситуации.

      In thread1:
           dictDemo[callid]=val
      in thread2:
           for key in dictDemo:   
                    if key in dictDemo:
                            dictDemo.pop(key,None)

Я столкнулся с ошибкой 'RuntimeError: словарь изменил размер во время итерации' в потоке 2, так как поток 1 работает в то же время. ** Как я могу использовать GIL для блокировки словаря dictDemo в потоке 2? ** Или GIL может использоваться только для потоков? Или есть способ заблокировать словарь, чтобы ограничить использование объекта двумя потоками одновременно?


person titto.sebastian    schedule 27.03.2015    source источник
comment
вы можете использовать объект threading.Lock.   -  person SolaWing    schedule 27.03.2015


Ответы (1)


Использование GIL для защиты кода Python небезопасно — трудно понять, когда вы потеряете GIL. GIL предназначен для защиты интерпретатора, а не вашего кода.

Вам нужно сериализовать использование словаря, и самый простой способ — использовать объект Lock.

from threading import Lock
dLock = Lock()

В потоке 1:

dLock.acquire()
dictDemo[callid]=val
dLock.release()

в потоке 2:

dLock.acquire()
for key in dictDemo.keys():   
     #if key in dictDemo:   <-- not required!
     dictDemo.pop(key,None)
dLock.release()

Кстати, здесь может пригодиться dictDemo.clear(), если все, что вы хотите сделать, это очистить словарь.

person cdarke    schedule 27.03.2015