is python dict.items() threadsafe?
<p>Python raises an exception if a dictionary changes its size during iteration using <code>iteritems()</code>.</p>

<p>I am hit by this problem since my program is <em>multithreaded</em> and there are cases that I need to iterate over the <code>dict</code> while another thread is adding keys into the <code>dict</code>.</p>

<p>Fortunately, I don't need the iteration to be very precise on every element in the <code>dict</code>. Therefore I am thinking to use <code>items()</code> instead of <code>iteritems()</code> to do the iteration. I think <code>items()</code> makes a static snapshot of the <code>dict</code> and I would work around the problem. </p>

<p>My question is: does <code>items()</code> raises an exception if the <code>dict</code> size is changing at the same time with <code>items()</code> execution?</p>

<p>thanks</p>

<p>As the excellent comments noted:</p>

<ol>
<li><p>This is not thread safe.</p></li>
<li><p>You should really use a lock when doing such things.</p></li>
</ol>

<p>It is possible to see this in <a href="https://svn.python.org/projects/python/trunk/Objects/dictobject.c" rel="nofollow">the CPython source code, <code>dictobject.c</code></a>:</p>

<p>If you look at the function</p>

<pre><code>static PyObject *
dict_items(register PyDictObject *mp)
</code></pre>

<p>which is used for <code>items</code>, you can see that (after some clever pre-allocation for the results), it basically iterates over the array <code>mp-&gt;ma_table</code> (using a mask to see where there are entries).</p>

<p>Now if you look at the function</p>

<pre><code>static int
dictresize(PyDictObject *mp, Py_ssize_t minused)
</code></pre>

<p>which is used when the table needs to be resized, then you can see that <code>ma_table</code>'s elements can be moved into a completely different buffer, and then it can be freed using <a href="https://docs.python.org/3.1/c-api/memory.html#PyMem_Free" rel="nofollow"><code>PYMem_Free</code></a>.</p>

<p>So, you have a very real risk of accessing garbage memory, if things are done concurrently without synchronization.</p>

python multithreading dictionary