【问题标题】:Sharing very large objects between processes / threads from within a class?在一个类中的进程/线程之间共享非常大的对象?
【发布时间】:2018-01-26 05:08:49
【问题描述】:

我有一个 Python 类,我想在其中生成线程或进程以共享数据,而不是跨线程或生成的进程复制它们。这是我正在尝试做的抽象。

class ClassA(object):
  def work(self, bigDictionary, bigList):
      param1 = self.getDictParam(bigDictionary)
      param2 = self.getListParam(bigList)
      return self.someOtherWork(param1, param2)

  def parallelizeWork(self, listOfBigDictionaries, listOfBigLists):
      result = # PARALLEL WORK ON EACH PAIR OF DICTIONARY AND LIST
      return result

您可以意识到我的任务(受处理器限制)是令人尴尬的并行,我尝试了多处理。不幸的是,因为我传递的对象很大,它们会触发酸洗错误。我真的不希望进程或线程复制数据,因为work 及其调用的函数不会修改任何对象;相反,我会让他们简单地从对象中读取。有没有合适的方法在 Python 中做到这一点?

【问题讨论】:

  • work i/o 绑定还是处理器绑定?
  • 处理器绑定
  • 是什么让您认为对象的大小导致了酸洗错误?你读过文档中的Sharing state between processes 吗?
  • @wwii 抛出的错误字面意思是,不能腌制超过 2 GiB 的对象。
  • 您可能需要提供有关如何使用大共享对象的更多信息。但我认为如果你使用多线程而不是多处理,它将避免酸洗,因此可以工作。

标签: python multithreading parallel-processing shared-memory


【解决方案1】:

假设我们谈论的是 CPython...

如果您可以在知道如何生成 GIL 的 Python 扩展(如 numpy)中完成计算工作,那么使用线程(如 Will 建议的那样)将很有效。

否则,在 POSIX 系统上,您可以将 multiprocessingfork 一起使用,但不能使用 exec,这在理论上避免了物理上使用 COW 分叉复制数据。然而,普通 Python 代码对引用计数的不断摆弄逐渐破坏了操作系统在进程副本之间的共享。即使在每个进程结束时重新分配数据也很容易使所需的内存膨胀。但如果你有 large 个对象(如长字符串)而不是 许多 个对象(如长列表),那可能没问题。

【讨论】:

  • 值得注意的是instagram已经在这个话题上做了some nice work
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-22
  • 1970-01-01
  • 1970-01-01
  • 2011-04-09
  • 1970-01-01
  • 2010-10-14
  • 2011-04-06
相关资源
最近更新 更多