Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How could I use GIL for a dictionary in a multithreaded application?

I have encountered error 'RuntimeError: dictionary changed size during iteration' while iterating through a dictionary in a thread,which is being inserted in another thread in Python 2.7.I found that by using Global Intrepreter Lock,we could lock a object in mutithreaded situation.

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

I encountered the error 'RuntimeError: dictionary changed size during iteration' in thread2 since thread1 works in the same time.**How can I use GIL to lock the dictDemo dictionary in thread2?**Or GIL can be used only for threads?Or is there a way to lock the dictionary so that to restrict the use of the object by 2 thread at a time?

like image 749
titto.sebastian Avatar asked Sep 28 '22 10:09

titto.sebastian


1 Answers

Using the GIL to protect your Python code is not safe - it is difficult to know when you are going to loose the GIL. The GIL is there to protect the interpreter, not your code.

You need to serialise the use of the dictionary, and the easiest way is to use a Lock object.

from threading import Lock
dLock = Lock()

In thread1:

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

in thread2:

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

By the way, dictDemo.clear() might be useful here if all you want to do is to clear the dictionary.

like image 116
cdarke Avatar answered Oct 31 '22 16:10

cdarke