threads: not locking read-only objects
Robert Brewer
fumanchu at amor.org
Sat Aug 7 02:07:37 EDT 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\threading.py", line 436, in __bootstrap
self.run()
File "C:\Python23\lib\threading.py", 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
MIS
Amor Ministries
fumanchu at amor.org
More information about the Python-list
mailing list