我想写一个小程序,对我来说可以代表彩票中奖的机会。之后,我想通过实现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
有人可以向我解释吗?(我是多处理的新手)
答案 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, ))
不要忘记将函数参数包装在元组中。