![](/img/trans.png)
[英]Python - SystemError: NULL result without error in PyObject call
[英]SystemError: NULL result Multiprocessing Python
我正在使用一个多处理池来训练机器学习者。
每个LearnerRun对象都有一个学习器,一个超参数字典,一个名称,另一个选项字典中的更多选项,要向其中写入结果的目录的名称,一组要在其上进行训练的示例ID(切片或numpy数组) ,以及一组要测试的示例ID(也包括slice或numpy数组)。 重要的是,尚未读取培训和测试数据:ID的集合相对较小,并指示后续功能的数据库读取行为。
我叫self.pool.apply_async(learner_run.run)
,以前很好。 现在,该池似乎已加载完毕,但是从不打印run()函数顶部的打印语句,因此实际上并没有运行这些进程。
我已经找到了一些有关此其他线程 ,我发现我可以在更多的细节看这个问题handler = self.pool.apply_async(learner_run.run)
然后handler.get()
这将打印“ SystemError:PyObject_Call中没有错误的NULL结果”。
太好了,我可以用Google来做。 但是我在Multiprocessing上可以找到的所有问题是,将太大而无法腌制的参数传递给子流程时,可能会导致这种情况。 但是 ,很明显,我没有给子进程传递任何参数。 那有什么呢?
除了超出分配的内存大小的参数(我可以肯定地确定这不是问题)之外,还能导致apply_async给出空结果吗?
再说一次,这在我去度假之前一直有效,并且没有改变。 对其他代码进行哪些类型的更改可能会导致该代码停止工作?
如果我不尝试从处理程序中get()
以便执行不会因错误而停止,则内存使用情况将遵循这种奇怪的模式。
好的,我发现了问题。 事实上,我LearnerRun 太大的多重处理。 但是它的方式非常微妙,因此我将对其进行描述。
显然,不仅需要腌制论据,还需要腌制这些论据。 该函数也会被腌制,包括其执行将依赖的LearnerRun
对象( self
)。
LearnerRun的构造函数将传递给它的选项字典中的所有内容用作对象,并使用setattr将所有键和值转换为具有值的成员变量。 仅此一个就好,但是我的同事意识到这留下了一些字符串,需要将其self.trainDatabase = LarData(self.trainDatabase)
数据库引用,并设置self.trainDatabase = LarData(self.trainDatabase)
和self.coverageDatabase = LarData(self.coverageDatabase)
,通常没事的。
除此之外,这意味着要腌制该类,您必须腌制整个数据库! 我在进行健全性检查时发现了这一点,其中只是序列化了LearnerRun本身,以查看pickle.dumps(learner_run)
会发生什么。 我的记忆被淹没了,交换开始迅速惊人地填满,直到stackoverflow为止。
那么如何腌制到磁盘呢? pickle.dump(learner_run, filename)
也被炸掉了。 我终止之前达到了14.3 GiB!
删除那些引用并在以后需要时调用LarData构造函数该怎么办? am 固定。 一切正常。 多重处理不再带来神秘的SystemError了。
这是泡菜最近第二次给我造成重大痛苦。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.