它可以在python 3.2中的循环中进行多处理吗?

时间:2011-08-27 00:37:20

标签: python loops multiprocessing

我正在尝试使用python(3.2)进行多进程(ubuntu)来解决大量搜索问题。基本上我想拿一个列表,取出第一个项目,找到与对象具有相同属性的所有其他项目,将找到的项目和目标项目连接到一个列表中,从原始列表中删除它们,然后(循环)重做一次。多处理旨在将处理器之间的工作分开。代码执行一次没有问题。事实上它也会循环,因为例外被忽略了,似乎做得很好。但是在30秒内,它几乎耗尽了我所有16GB的RAM。

到目前为止,我的两个问题是1)我得到“异常断言错误:AssertionError('只能测试子进程'),忽略”只要我循环(我得到了很多)。除此之外还有大量的RAM使用(我认为这可能是相关的,不确定)。 AND 2)当我使用更大的数据集时,它似乎甚至没有并行执行搜索。

我的代码如下:

class triangleListWorker(multiprocessing.Process):
    def __init__(self, work_queue, target, results,start):
        super().__init__()
        self.work_queue = work_queue
        self.results = results
        self.target = target
        self.startIndex = start
    def run(self):
        while True:
            try:
                searching = self.work_queue.get()
                self.do_search(searching)

            finally:
                self.work_queue.task_done()

    def do_search(self,searching):
        for x in range(len(searching)):
            if self.target.same_plane(searching[x]):
                self.results.append(self.startIndex+x)

我在这里尝试做的是使用Manager()。list()来存储目标对象和搜索对象存在于同一平面上的所有索引。

    def do_multi_find_connections(self, target,searchList):
        work_queue = multiprocessing.JoinableQueue()
        #results= multiprocessing.Queue()

        cpu_count = multiprocessing.cpu_count()
        results = multiprocessing.Manager().list()
        range_per_process = len(searchList) // cpu_count
        start,end = 0, range_per_process + (len(searchList) % cpu_count)
        for i in range(cpu_count):
            worker = triangleListWorker(work_queue,target,results,start)
            worker.daemon = True
            worker.start()
        for x in range(cpu_count):
            searchsub = [searchList[x] for x in range(start,end)]
            work_queue.put(searchList[start:end])
            #work_queue.put(searchList[start:end])
            start,end = end, end + range_per_process
            print(start,end)

        work_queue.join()
        print( "can continue...")

        return results

    def find_connections(self, triangle_list,doMultiProcessing):
        tlist = [x for x in triangle_list]
        print("len tlist", len(tlist))
        results = []
        self.byPlane = []
        if doMultiProcessing:
            while len(tlist) > 0:
                results = []
                target = tlist[0]
                #print("target",tcopy[0])
                self.do_multi_find_connections(target,tlist)

                results = self.do_multi_find_connections(target,tlist)#list of indexes
                plane = []

                print(len(results))
                print(results)
                for x in results:
                    plane.append(tlist[x])
                new_tlist = [tlist[x] for x in range(len(tlist)) if not x in results]
                print(len(new_tlist))
                tlist = new_tlist

                self.byPlane.append(plane)

##                self.byPlane.append(plane)
##                tlist = []

这段代码(可能有点难看)应该循环找到下一个平面,并通过调用它上面的函数(进行多处理)来耗尽平面中的所有其他平面。

在Ubuntu 11.04 64上运行,python 3.2。

2 个答案:

答案 0 :(得分:1)

我认为multiprocessing模块的目标模式是创建Pool并使用Pool.map_async方法,而不是使用循环。 IOW,将你的循环转换为某种迭代器(可能是generator方法)。然后将等效的do_search方法作为函数,将迭代器传递给map_async

答案 1 :(得分:0)

您可以在多处理中使用Pool类:

from multiprocessing import Pool
pool = Pool(processes=5)
valuesProcessed = pool.map(someFunction, valuesToProcess)