Home  >  Q&A  >  body text

python - multiprocessing中用进程池apply_async出现的莫名错误

以下是我的代码片段

import multiprocessing
@fn_timer
def getEnergyTerm(size , elements , elementSize , elementType , elementLine , elementGroup , imageElement , Dis , background):
    pdb.set_trace()
    functionList = [alignCalc , whiteSpace , getBalanceGravityCenter , spread , dist , margin , textSize , textVar , minTextSize , textContrast , textOverlap , graphicTextOverlap , graphicBoundary ,  groupSizeVar , groupDistMean]
    pool = multiprocessing.Pool()

    result = []
    #whiteSpace(size , elements , elementSize , elementType , elementLine , elementGroup , imageElement , background)
    #pool.apply_async(whiteSpace , args = (size , elements , elementSize , elementType , elementLine , elementGroup , imageElement , background))
    for func in functionList:
        result.append(pool.apply_async(func , args = (size , elements , elementSize , elementType , elementLine , elementGroup , imageElement , background)))

    pool.close()
    pool.join()
    print result
    energy = {k:v for item in result for k , v in item.get().items()}
    return energy

这里的functionList中的function类似于下面这样子的:

def whiteSpace(size , elements , elementSize , elementType , elementLine , elementGroup , imageElement , background):
    #pdb.set_trace()
    sum = size[0] * size[1]
    for item in range(len(elements)):
        sum -= elementSize[item][0] * elementSize[item][1]

    sum = sum * 1.0 / (size[0] * size[1])

    E_white_space =  -1.0 * sigmod(sum , alpha)
    res = {}
    res['whiteSpace'] = E_white_space
    return res

我使用pdb调试的时候,会在apply_async处出现错误,错误信息如下:

Traceback (most recent call last):
  File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
    self.run()
  File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/lib/python2.7/multiprocessing/pool.py", line 102, in worker
    task = get()
  File "/usr/lib/python2.7/multiprocessing/queues.py", line 376, in get
    return recv()
TypeError: __new__() takes exactly 4 arguments (2 given)

实在想不到错在哪了,因为我不是很熟悉multiprocessing这个包,本来想优化下程序的速度,参考了这篇文章的方法,但是出的错误不是很理解,求高手解答 , 谢谢

PHP中文网PHP中文网2765 days ago637

reply all(1)I'll reply

  • 黄舟

    黄舟2017-04-18 10:05:05

    I think I have solved this problem, but I still don’t know where the problem lies. In pool.apply_async(func , args = (size , elements , elementSize , elementType , elementLine , elementGroup , imageElement))中原本有background参数,但是在删除这个参数之后程序就跑通了,而background = Image.open('background.png'), it is an object. I originally thought it was because apply_async cannot pass object type values, but I tested it with the following program and rejected it. My guess:

        import multiprocessing
        from PIL import Image
    
        def testFunc(y , x , calcY, list , str , img):
            a = [i*i for i in x]
            #b = [i+i for i in y]
            b = y[0]
            c = [i+i for i in list]
            res = {}
            res['a'] = a
            res['b'] = b
            res['c'] = c
            res['str'] = str
            img.paste(0 , (100 , 100 , 100 , 100))
            res['img'] = img
    
            return res
    
    
    
        if __name__ == '__main__':
            p = multiprocessing.Pool()
            img = Image.new('RGBA' , (800 , 600))
            res = p.apply_async(testFunc , args = ((2 , 3) , [2 , 3 , 4] , False , [6 , 7 , 8 , 9] , 'hello world' , img))
            print res.get()

    This program works, so the problem is solved, but I still don’t understand the principle. I hope someone can give me a hint

    reply
    0
  • Cancelreply