2010-08-10 37 views
6

我有一个复杂的数据结构(用户定义类型),在其上执行大量的独立计算。数据结构基本上是不可变的。我基本上说,因为尽管界面看起来不可变,但内部还是有一些懒惰评估正在进行。一些延迟计算的属性存储在字典中(通过输入参数返回昂贵函数的值)。 我想用Pythons multiprocessing模块来并行化这些计算。我脑海中有两个问题。在Python中的进程之间共享数据

  1. 如何最好地共享进程之间的数据结构?
  2. 有没有办法处理惰性评估问题,而不使用锁(多个进程写入相同的值)?

在此先感谢您的任何答案,意见或启发性问题!

+0

你在说多大/多复杂?当提交“独立计算”时,您是否知道在开始之前需要哪些惰性属性? – MattH 2010-08-10 10:24:45

+0

这个问题基本上是对大量数据样本的一次性交叉验证。我的机器在单个内核上需要花费大约两个小时,但我可以使用24个内核的机器,并希望利用此功能。我事先不知道哪一个属性会被一次计算所需要,但是我知道最终(在所有计算中)所有属性都将被需要,所以我可以将它们全部加载到前面(但必须测试)。 – 2010-08-10 10:30:17

回答

8

如何最好地共享进程之间的数据结构?

管道。

origin.py | process1.py | process2.py | process3.py 

打破你的程序,使每个计算是一个单独的下列形式的过程。

def transform1(piece): 
    Some transformation or calculation. 

对于测试,您可以像这样使用它。

def t1(iterable): 
    for piece in iterable: 
     more_data = transform1(piece) 
     yield NewNamedTuple(piece, more_data) 

要在单个进程中重现整个计算,您可以执行此操作。

for x in t1(t2(t3(the_whole_structure))): 
    print(x) 

你可以用一点文件I/O来包装每个转换。 Pickle适用于此,但其他表示(如JSON或YAML)也可以很好地工作。

while True: 
    a_piece = pickle.load(sys.stdin) 
    more_data = transform1(a_piece) 
    pickle.dump(NewNamedTuple(piece, more_data)) 

每个处理步骤成为一个独立的OS级进程。它们将同时运行,并立即 - 消耗所有操作系统级资源。

有没有办法处理懒惰评估问题,而不使用锁(多个进程写入相同的值)?

管道。

+0

哇,这答案解决了两个问题,即使在我的问题甚至没有(如何发送复杂的对象到另一个进程,如何在多处理模块不可用时在python中执行此操作)! – 2010-08-10 10:22:59

+0

关键是OS级(共享缓冲区)进程管理(a)更简单,(b)可以像更复杂的多线程,共享任何技术一样快。 – 2010-08-10 11:08:06