我有一个multiprocessing.manager.BaseManager
实现,其中共享资源是一个返回各种数据的DataFrames的类。我遇到的问题是,由于pandas不是线程安全的,因此进程正在共享它们正在操作的数据的实例。这导致Python崩溃了。
我尝试过做的是在多处理管理器类中覆盖MakeProxyType
方法(请参阅:https://github.com/python/cpython/blob/8c83c23fa32405aa9212f028d234f4129d105a23/Lib/multiprocessing/managers.py#L938)来执行此操作:
for meth in exposed:
if meth.startswith("load"):
exec('''def %s(self, *args, **kwds):
return self._callmethod(%r, args, kwds).copy()''' % (meth, meth), dic)
else:
exec('''def %s(self, *args, **kwds):
return self._callmethod(%r, args, kwds)''' % (meth, meth), dic)
然而,它实际上并没有给我数据的副本。当我看到输出变量时,我看到有些共享相同的内存地址(用相同的星号表示):
Thread 1: 0xa225630 ***
Thread 2: 0xa245518 *
Thread 3: 0xa225518 *
Thread 4: 0xa225518 *
Thread 5: 0xa2284a8
Thread 6: 0xa225550 **
Thread 7: 0xa245550 **
Thread 8: 0xa245630
Thread 9: 0xa225630 ***
当我尝试在进程内部使用pandas操作数据时,会导致问题。
任何人都可以帮助我吗?关于如何强制多处理管理器给我这些DataFrame的唯一实例的任何想法,以便我可以避免崩溃python?多处理管理器似乎是一个非常好的类 - 但它的文档相当薄。
答案 0 :(得分:0)
所以我仍然没有100%问题在这里,但是multiprocessing
库中有一个名为ThreadPool
(https://github.com/python/cpython/blob/master/Lib/multiprocessing/pool.py)的未记录的类。它不仅具有开启线程的开销少于进程的好处,而且管理器现在返回每个DataFrame
的不同副本!