在Python中优化多处理

时间:2014-02-23 18:01:20

标签: python multiprocessing

我正在尝试学习使用Python的多处理模块。为此,我试图解决ProjectEuler.net中的问题,因为它们是并行处理的良好候选者。以下代码基于problem 14,要求您找到1,000,000以下最长的Collat​​z链。我最初的解决方案是抛弃1,000,000个流程并尝试解决它们 - 这是一场灾难。我的第二次尝试(下面的解决方案)将问题分解为numProcs块。

我的问题是,有没有办法让这次运行得更好?有没有办法在不事先将问题分解为块的情况下执行此操作,即有没有办法动态地对任务处理器执行任务。用简单的英语,我怎么说“OOoo!处理器1完成了它的问题,让我们再给它一个。”而不是“这是你的总工作负载处理器1。”?

def run2(j):
    """
    A multicore implementation of the collatz sequence
    j - the largest number whose Collatz Chain we need to check
    """
    from multiprocessing import Process, Value, cpu_count
    import math

    def bazinga(nums, maxChain, biggest):
        """
        generates the length of the collatz chain for each
        number in list 'nums', it determines the longest chain
        and the number that determines the longest chain and 
        writes them to shared memory 'maxChain' and 'biggest'
        """
        for i in nums:
            a = len(generateChain(i, []))
            if a >= maxChain.value:
                biggest.value = i
                maxChain.value = a   

    numProcs = cpu_count()
    chunksize = math.ceil(j/numProcs) #Total number to solve / #cpus

    maxChainSize = Value('I', 0)
    largestChainProducer = Value('I', 0)

    #generate the "chunks"
    numList = []
    for i in range(numProcs): numList.append([])
    for i in range(1, j):
        numList[i%numProcs].append(i) #allocate the numbers in to buckets

    ps = []
    for i in range(numProcs):
        p = Process(target=bazinga, args=(numList[i], maxChainSize, largestChainProducer))
        p.start()
        ps.append(p)
    for p in ps: p.join()

    print('%s has a chain of length %s' % (largestChainProducer.value, maxChainSize.value))

1 个答案:

答案 0 :(得分:1)

尝试使用队列将作业传递到正在运行的进程并返回结果。当您准备好运行时,您的正在运行的进程将从队列中弹出下一个作业。

python multiprocessing docs中有一些很好的例子。