"RuntimeError: dictionary changed size during iteration" ; Good atomic copy operations?

EleSSaR^ usenetpublic-elessar.xyz at yahoo.it
Sat Mar 11 22:07:44 EST 2006


robert si è profuso/a a scrivere su comp.lang.python tutte queste
elucubrazioni: 

> Yes, a "backup" / autosave while all threads are running. It doesn't 
> matter if 'before' of 'after' another item has been added/deleted 
> atomically.

But it does matter if the autosave happens *while* an item is being
updated, I suppose. E.g. if a single 'atomic' operation would change two
dictionaries, and an autosave triggers after the first has been changed and
the second hasn't, this would be an unwanted autosave, right?

>> By the way, you could try employing locks from other threads to dump the
>> object as well... this would prevent additional locking.
> 
> Don't understand.
> The threads work all simulatniously on the object tree, add and detach 
> atomically only valid sub-trees.

You're never using any lock, then? Isn't it possible that two threads try
changing the very same dict/list at the same time? Just one more question:
are you running your software on a single-cpu machine?

> change "subobj.x='y'" is a dictionary operation. That would make 
> threaded programming very arduous.

Well... threaded programming usually is a hard task. No surprise so many
people prefer async programming nowadays. It makes many things simpler.

> def rt_save_dict_copy()
>    tod={}
>    for k in fromd.keys():
>      try: tod[k]=fromd[k]
>      except: pass
>    return tod
> 
> without true iteration over the original dict whould copy without 
> RuntimeError.

But with no warranty of data consistency. It will prevent new values to be
computed, but if one value from the dict is modified during iteration, the
dict may be left in a never-existed state:

import random
random.seed()
fromd = {1:1, 2:2, 3:3, 4:4, 5:5}

print "dict before iteration:", fromd
def rt_save_dict_copy():
    tod={}
    for k in fromd.keys():
      try:
        tod[k]=fromd[k]
      except:
        pass
      fromd[random.choice(xrange(1,6))] = random.choice(xrange(1,10))
    return tod

print "copied dict:", rt_save_dict_copy()
print "dict after copy:", fromd




-- 
EleSSaR^ <usenetpublic-elessar.xyz at yahoo.it>
--
Togli .xyz dalla mia email per contattarmi.



More information about the Python-list mailing list