"RuntimeError: dictionary changed size during iteration" ; Good atomic copy operations?
robert
no-spam at no-spam-no-spam.com
Sat Mar 11 18:37:36 EST 2006
EleSSaR^ wrote:
> robert si รจ profuso/a a scrivere su comp.lang.python tutte queste
> elucubrazioni:
>
>
>>own deepcopy: thus, do you already know if the existing deepcopy has the
>>same problem as cPickle.dump ? (as the problem araises rarely, it is
>>difficult for me to test it out)
>
> I don't know the exact specs of your object, and I don't know what
> operations are you performing on that object, nor the way they're atomic.
There is not much to know. Python object trees consist only of dicts and
lists as far as variable non-atomic datastructures are concerned.
(unless you use advanced extension libs like NumPy)
Thus the RuntimeError problem is only about modified dicts/lists during
Iteration in pickly/copy.
> It seems like you're trying to save periodically the state of such object
> while it is being modified (a sort of backup?), and Python complains about
> that. A self-implemented deepcopy might raise anomalies (i.e. your dumped
> object may be partly a 'before' object and partly an 'after' object ) as
> well.
Yes, a "backup" / autosave while all threads are running. It doesn't
matter if 'before' of 'after' another item has been added/deleted
atomically.
> 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.
Regarding what AM said, I would have to lock _each_ dict/list operation
on the tree, thus almost each change, because even a single attribute
change "subobj.x='y'" is a dictionary operation. That would make
threaded programming very arduous.
AFAIK about the current Python implementation: This RuntimeError is only
thrown "during true Iteration over dict/list, when the number of items
changes". (and not when e.g. a single item is changed). Thus a
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.
(or maybe equivalent: "dict(fromd.items())" ? )
I don't know if dict.copy() works so - but I think so, as dict.keys()
and dict.items() have the same footprint.
The algorithm in cPickle.dump does not work so. Guess it does something
like "for k in fromd: ..."(!) internally. This might be a "90%-bug"?
Will have to see what copy/deepcopy does ...
Robert
More information about the Python-list
mailing list