threads: not locking read-only objects

Robert Brewer fumanchu at
Sat Aug 7 08:07:37 CEST 2004

Jon Perez wrote:
> Hmmm... here's what's going on.  I have a dictionary of
> logged in users called 'whoison' that's updated in the main
> thread (and only in the main thread) with a:
> whoison['username']="timeoflogin"  # to add someone new
> and
> del whoison['username']  # to remove someone who's logged out
> Do the above count as atomic?

Yes; however, that's not enough in your case. :)

> The worker threads do the following read-only operation:
> for x in whoison:
>    print x,whoison[x]
> Looking at the read-only code though I just realized
> something.... if a dictionary entry in 'whoison' is deleted
> by the main thread while the 'for x in whoison' is executing
> then what would happen?

You get an exception:

>>> import threading
>>> whoison = dict.fromkeys(xrange(100000))
>>> def iterate():
... 	for a in xrange(1000):
... 		for x in whoison:
... 			42
... 	print "Done"
>>> threading.Thread(None, iterate).start()
>>> del whoison[333]
>>> Exception in thread Thread-11:
Traceback (most recent call last):
  File "C:\Python23\lib\", line 436, in __bootstrap
  File "C:\Python23\lib\", line 416, in run
    self.__target(*self.__args, **self.__kwargs)
  File "<interactive input>", line 3, in iterate
RuntimeError: dictionary changed size during iteration

> Looks like I'm going to need a lock after all even for the
> read-only operations...?

Yup. Or use some other trick, like:

for k in whoison.keys():
    v = whoison.get(k)
    print k, v

...which iterates over a copy of the keys instead of the keys
themselves. Other, more complicated techniques exist. You'll soon
understand why many gurus declare concurrency to be one of the recurring
"hard problems" of programming. ;)

Robert Brewer
Amor Ministries
fumanchu at

More information about the Python-list mailing list