a real workaround is not possible without rewriting dump or deepcopy -
I use this multi-try on RuntimeError so far, but thats not "legal Python
code" )
Why rewrite deepcopy?
Given how much time has gone into this thread, I've reached the
conclusion one could have coded a solution faster...
Let's see... One complaint is that all accesses to the dictionary
object being archived would need to be wrapped by locks...
Has anyone suggested that, instead of using the plain Python
dictionary, one replace (subclass/extend) dictionary to create a
protected dictionary -- that is, one in which all the "magic" access
methods are overridden to include the lock operation (and an instance
specific lock). Thereby, the rest of the code never sees the locks --
and only the code that initially creates the dictionary changes:
shared_copy = {}
replaced by:
shared_copy = Protected_Dict()
THEN, for purposes of the archival dump, give the protected
dictionary a deepcopy method, which locks at the start, makes the copy
(a regular dictionary is good enough, but to properly deepcopy it should
also be a protected version) using the base class methods, unlocks, and
returns the copy. The thread that creates the archival dump would only
need to invoke something like:
dump_copy = shared_copy.deepcopy()
and then perform the pickle or whatever on "dump_copy" -- that will be
static while the other threads may continue to process. The lock during
the "deepcopy" operation will only block those threads actually trying
to update the object -- whereas the proposed global threading lock would
affect ALL threads, and you'd still have to remember to wrap the
copy/pickle operation with those calls.
Maybe parallel this with a Protected_List... And if you have lists
inside the dictionary, a bit more code modification to ensure they are
initialized as protected types.
If I understand the system, unpickling may or may not be affected --
if you can unpickle on a node by node basis, and use regular (protected)
operations to recreate the main object...
That "practical hammer" (little ugly, but very practical) would enable
to keep big threaded code VHL pythonic and keep us from putting
thousands of trivial locks into the code in low level language manner.
Some OS-functions like those of the socket module (on UNIX) do so anyway
( often unwanted :-( )
That "hammer" sounds like Windows 95, having to drop into some near
"real mode" to do I/O, then back to VM mode for processing.
I may switch to a solution with subclassed deepcopy withough
.iteritems(). But its lot of work to ensure,that it is really ok - and
consumes another few megs of memory and a frequent CPU peakload. So I
may leave the loop and may probably not switch at all ...
As mentioned above, I think you may be subclassing the wrong item...
You should subclass the dictionary/list that is giving you the problem
and make /it/ behave safely by adding a deepcopy operation to it.
--