threads: not locking read-only objects

Heiko Wundram heikowu at ceosg.de
Sat Aug 7 05:53:26 EDT 2004


Am Samstag, 7. August 2004 04:58 schrieb Jon Perez:
> whoison['username']="timeoflogin"  # to add someone new
>
> del whoison['username']  # to remove someone who's logged out
>
> Do the above count as atomic?

Yup, both of them are atomic. But: If you use different dictionary keys than 
strings, you're in for a little surprise, as __hash__ing an object can cause 
Python to be called, which might be suspended by a thread switch.

The dictionary object will still be in perfect order (it'll never be in an 
inconsistent state), but the key reference won't be in the dictionary yet.

> 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?

Now, this is something different. You can easily try what happens by doing the 
following:

whoison = {"heiko":"at home","heiko2":"at work"}
for x in whoison:
	print x, whoison[x]
	del whoison[x]

Traceback (most recent call last):
  File "<stdin>", line 1, in ?
RuntimeError: dictionary changed size during iteration

That's the same exception you'll get when another thread changes the python 
dict while you're iterating over it.

What you might do:

# The following makes a static copy of the keys of the dictionary.
for x in whoison.keys():
	try:
		val = whoison[x]
	except KeyError:
		continue
	print x, val

Or just acquire a thread lock before processing the dictionary, which might 
actually be the easiest solution. ;)

Heiko.



More information about the Python-list mailing list