从另一个进程获取列表时出错

时间:2018-08-27 08:34:06

标签: python-3.x multiprocessing

我想写一个小程序,对我来说可以代表彩票中奖的机会。之后,我想通过实现this

之类的多处理来使其速度更快

但是出现了两种奇怪的行为

import random as r
from multiprocessing.pool import ThreadPool



# winnerSequence = []
# mCombinations = []

howManyLists = 5
howManyTry = 1000000
combinations = 720/10068347520


possbilesNumConstantsConstant = []
for x in range(1, 50):
    possbilesNumConstantsConstant.append(x)

def getTicket():
    possbilesNumConstants = list(possbilesNumConstantsConstant)

    toReturn = []
    possiblesNum = list(possbilesNumConstants)

    for x in range(6):
        choice = r.choice(possiblesNum)
        toReturn.append(choice)
        possiblesNum.remove(choice)
    toReturn.sort()
    return toReturn


def sliceRange(rangeNum,num):
    """returns list of smaller ranges"""
    toReturn = []
    rest = rangeNum%num
    print(rest)
    toSlice = rangeNum - rest
    print(toSlice)
    n = toSlice/num
    print(n)
    for x in range(num):
        toReturn.append((int(n*x),int(n*(x+1)-1)))
    print(toReturn,"<---range")
    return toReturn

def Job(tupleRange):
    """Job returns list of tickets """
    toReturn = list()
    print(tupleRange,"Start")
    for x in range(int(tupleRange[0]),int(tupleRange[1])):
        toReturn.append(getTicket())
    print(tupleRange,"End")
    return toReturn


result = list()

当我将Job(tupleRange)添加到池中时,第一个看起来是作业在主线程中完成,然后再将另一个作业添加到池中

def start():
    """this fun() starts program"""

    #create pool of threads
    pool = ThreadPool(processes = howManyLists)

    #create list of tuples with smaller piece of range
    lista = sliceRange(howManyTry,howManyLists)

    #create list for storing job objects
    jobList = list()
    for tupleRange in lista:
        #add job to pool
        jobToList = pool.apply_async(Job(tupleRange))
        #add retured object to list for future callback
        jobList.append(jobToList)
        print('Adding to pool',tupleRange)

    #for all jobs in list get returned tickes
    for job in jobList:
        #print(job.get())
        result.extend(job.get())

if __name__ == '__main__':
    start()

Consol输出

[(0, 199999), (200000, 399999), (400000, 599999), (600000, 799999), (800000, 999999)] <---range
(0, 199999) Start
(0, 199999) End
Adding to pool (0, 199999)
(200000, 399999) Start
(200000, 399999) End
Adding to pool (200000, 399999)
(400000, 599999) Start
(400000, 599999) End

第二个是当我想从线程中获取数据时,在此行上出现了此异常

for job in jobList:
        #print(job.get())
        result.extend(job.get())  #<---- this line



File "C:/Users/CrazyUrusai/PycharmProjects/TestLotka/main/kopia.py", line 79, in start
    result.extend(job.get())
  File "C:\Users\CrazyUrusai\AppData\Local\Programs\Python\Python36\lib\multiprocessing\pool.py", line 644, in get
    raise self._value
  File "C:\Users\CrazyUrusai\AppData\Local\Programs\Python\Python36\lib\multiprocessing\pool.py", line 119, in worker
    result = (True, func(*args, **kwds))
TypeError: 'list' object is not callable

有人可以向我解释吗?(我是多处理的新手)

1 个答案:

答案 0 :(得分:1)

问题在这里:

jobToList = pool.apply_async(Job(tupleRange))

Job(tupleRange)首先执行,然后apply_async获得一些返回值,类型为list(因为Job返回列表)。这里有两个问题:此代码是 synchronous ,并且async_apply获取list而不是它期望的工作。因此它尝试将给定列表作为作业执行,但是失败。

这是pool.apply_async的签名:

def apply_async(self, func, args=(), kwds={}, callback=None,
            error_callback=None):
     ...

因此,您应该将func和参数args分别发送到该函数,并且在将其发送到池之前,请勿执行该函数。

我已修复此行,并且您的代码对我有用:

jobToList = pool.apply_async(Job, (tupleRange, ))

或者,使用显式命名的args

jobToList = pool.apply_async(func=Job, args=(tupleRange, ))

不要忘记将函数参数包装在元组中。