问题
I'm trying to create a copy of a class instance that I can simulate without affecting the original instance of the class. I've tried using copy.copy
, but I run into this problem:
system.simulate(until=100)
print(system.env.now) # prints 100
copy_of_system = copy.copy(system)
copy_of_system.simulate(until=200)
print(copy_of_system.env.now) # prints 200
print(system.env.now) # prints 200, but should print 100
When I use copy.deepcopy
I get TypeError: can't pickle generator objects
. Is there any effective way to create an independent copy of the system
object?
回答1:
I'm very interested in this topic too. After all, forking scenarios in a simulation, after a long and expensive common first part, would be of immense value; currently we have to rerun everything. I tried to find a solution in the last couple days, for now without success.
The explanation for the generator-related error is here: Why can't generators be pickled?
One possible solution could be to use the pypy
interpreter, because, as mentioned there, it offers the stackless-like feature of being able to pickle generators.
I first tried to use pypy3.6
, because my program is written in Python3, but failed. Using dill
did not help. I found the explanation here: https://bitbucket.org/pypy/pypy/issues/3150/can-pickle-generators-in-27-but-not-on-36
Assuming this is the only roadblock, translating the program in Python2 would allow to pickle the entire simpy.Environment
in pypy
.
Please share your results if anyone tries this; I will keep you up to date with mine.
EDIT: I could not get it to work with pypy
, even if it can pickle generators. pickle
does not serialize. dill
serializes, but when loading the serialized string stumbles in some AttributeError. I don't know if this would happen with any environment or just my complex one - which I need as is. If I'll find the time, I will try to serialize simpler environments. If anybody manages to pickle a full Environment, please let us know.
回答2:
One way of having an existing simpy.Environment
take several different paths of execution in parallel would be to use os.fork()
when you're done setting up the Environment. You then can, for example, leverage the interprocess communication primitives in multiprocessing
, such as Queues
, etc, for collecting the interesting results of the different simulations. This requires writing a fair amount of boilerplate associated with manual forking, but it can be more than worth it.
NB: os.fork()
, that I know of, is available only under Unix-like OSes.
来源:https://stackoverflow.com/questions/58415397/what-is-the-easiest-way-to-copy-a-class-instance-that-contains-simpy-processes