What is the easiest way to copy a class instance that contains SimPy processes?

天涯浪子 提交于 2020-01-24 20:14:45

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!