Python与多进程,将集合生成分解为子进程

0 投票
3 回答
1344 浏览
提问于 2025-04-16 07:34

我需要根据一些字符串的计算结果生成一组新的字符串。这过程花费的时间比较长,而我正在使用一个多处理器和多核心的服务器,所以我想把这些任务分成小块,交给不同的进程去处理。

首先,我把第一组字符串分成每组10000个的小块,发送给一个进程去创建新的字符串集,然后尝试获取一个锁,把这些结果报告回主进程。但是,我的主进程的结果集是空的!

这里有一段代码:

def build_feature_labels(self,strings,return_obj,l):
    feature_labels = set()
    for s in strings:
        feature_labels = feature_labels.union(s.get_feature_labels())
    print "method: ", len(feature_labels)
    l.acquire()
    return_obj.return_feature_labels(feature_labels)
    l.release()
    print "Thread Done"

def return_feature_labels(self,labs):
    self.feature_labels = self.feature_labels.union(labs)
    print "length self", len(self.feature_labels)
    print "length labs", len(labs)


current_pos = 0
lock = multiprocessing.Lock()

while current_pos < len(orig_strings):
    while len(multiprocessing.active_children()) > threads:
        print "WHILE: cpu count", str(multiprocessing.cpu_count())
            T.sleep(30)

    print "number of processes", str(len(multiprocessing.active_children()))
    proc = multiprocessing.Process(target=self.build_feature_labels,args=(orig_strings[current_pos:current_pos+self.MAX_ITEMS],self,lock))
    proc.start()
    current_pos = current_pos + self.MAX_ITEMS

    while len(multiprocessing.active_children()) > 0:
        T.sleep(3)


    print len(self.feature_labels)

奇怪的是,主进程中的self.feature_labels是空的,但在每个子进程中调用时却有内容。我觉得我可能走错了方向(这其实是我以前在Java中做的方式!)。有没有更好的方法呢?

提前谢谢你们。

3 个回答

0

为什么它不管用:多进程使用的是进程,而进程之间的内存是不能共享的。虽然多进程可以设置共享内存或者管道来进行进程间通信,但这些都需要手动去设置。这就是为什么各种建议能够把数据传回主进程的原因。

1

可以使用 multiprocessing.Pipe 或 Queue(或者其他类似的工具)来在不同的进程之间传递数据。用 Pipe 可以在两个进程之间传递数据,而用 Queue 则可以让多个生产者和消费者同时使用。

除了官方文档外,Doug Hellman 的多进程教程里也有很好的示例。特别是,它有一个关于如何使用 multiprocessing.Pool 来实现类似 mapreduce 操作的例子。这可能非常适合你的需求。

2

可以考虑使用一个工人池:http://docs.python.org/dev/library/multiprocessing.html#using-a-pool-of-workers。这个方法可以帮你完成很多工作,类似于“映射-归约”的方式,并且会把最终的结果整理好返回给你。

撰写回答