2013-10-30 4 views
4

py3.3 용 Python의 다중 처리 라이브러리를 탐색하려고하고 있는데 설명 할 수 없었던 map_async 함수의 이상한 결과를 발견했습니다. 나는 콜백에서 저장된 결과가 "고장난"것으로 예상했다. 즉, 여러 작업을 작업자 프로세스에 제공하면 일부 작업은 다른 작업보다 먼저 완료되어야합니다. 입력 순서와 함께 입력 순서에 있거나 입력 목록에 존재하지 않아도됩니다. 그러나 입력 된 작업과 완벽하게 일치하는 결과 집합이 나타납니다. 일부 프로세스를 고의적으로 "방해"하려고 시도한 후에도 이러한 경우가 발생합니다 (다른 프로세스가 이전에 완료 할 수 있음).파이썬의 map_async는 결과를 어떻게 유지합니까?

calculate 함수에 print 문이 있습니다. 즉, 결과가 인 경우 여전히 순서가 잘못되어있는 것으로 나타납니다. 사실 인쇄물이 실제로는 인 것의 위대한 지표로 신뢰할 수 있는지 확신 할 수 없지만 순서가 잘못되었습니다.

테스트 프로세스 (일반적인 예) : 정수가 들어있는 개체 목록을 작성하십시오. map_async에 대한 오브젝트 목록을 인수로, "calculate"함수와 함께 오브젝트의 numValue 속성에 제곱 값으로 제출하십시오. "calculate"함수는 업데이트 된 값을 가진 객체를 반환합니다.

일부 코드 : multiprocessing.Pool: When to use apply, apply_async or map?가 :

import time 
import multiprocessing 
import random 

class NumberHolder(): 
    def __init__(self,numValue): 
     self.numValue = numValue #Only one attribute 

def calculate(obj): 
    if random.random() >= 0.5: 
     startTime = time.time() 
     timeWaster = [random.random() for x in range(5000000)] #Waste time. 
     endTime = time.time()   #Establish end time 
     print("%d object got stuck in here for %f seconds"%(obj.numValue,endTime-startTime)) 

#Main Process 
if __name__ == '__main__': 
    numbersToSquare = [x for x in range(0,100)]  #I'm 
    taskList = [] 

    for eachNumber in numbersToSquare: 
     taskList.append(NumberHolder(eachNumber)) #Create a list of objects whose numValue is equal to the numbers we want to square 

    results = [] #Where the results will be stored 
    pool = multiprocessing.Pool(processes=(multiprocessing.cpu_count() - 1)) #Don't use all my processing power. 
    r = pool.map_async(calculate, taskList, callback=results.append) #Using fxn "calculate", feed taskList, and values stored in "results" list 
    r.wait()    # Wait on the results from the map_async 

results = results[0] #All of the entries only exist in the first offset 
for eachObject in results:  #Loop through them and show them 
    print(eachObject.numValue)   #If they calc'd "out of order", I'd expect append out of order 

나는 map_async는 "순서가"있는 결과를 얻을 수있는 아이디어를 지원하는 것이 아니라 서면 답변을 발견했다. 나는 또한 문서를 여기에서 보았다 (http://docs.python.org/3.3/library/multiprocessing.html). map_async의 경우이 메소드에 대해 "... 콜백이 지정되면 단일 인수를 허용하는 호출 가능이어야하며 호출이 실패하지 않는 한 결과가 준비 콜백이됩니다. 콜백은 그렇지 않으면 즉시 완료되어야합니다 결과를 처리하는 스레드가 차단됩니다. "

이것이 어떻게 작동하는지 오해하니? 어떤 도움이라도 대단히 감사합니다.

+0

응답 해 주셔서 감사합니다. @Blender. 그러면 간단한 질문으로 이어집니다. results.append에 대한 콜백의 경우 모든 결과가 준비되면 추가 작업 만 수행됩니까? 문서를 읽으면서 각 결과를 사용할 수있게되자 전화가 왔다고 생각했습니다. "결과가 준비 콜백이 적용될 때" – Thomas

답변

6

예상되는 동작입니다. 문서는 다음과 같이 말합니다.

결과 개체를 반환하는 메서드의 변형입니다.

"결과 개체"는 계산 된 결과를 보관하는 컨테이너 클래스입니다. r.wait()에 전화 할 때 까지 기다리십시오. 결과 중 모두을 집계하여 순서대로 입력하십시오. 순서가 잘못된 작업을 처리하더라도 결과는 원래 순서대로 유지됩니다.

결과가 산출 될 때 산출되도록하려면 imap_unordered을 사용하십시오.

+0

고마워요. - 이것은 매우 유용합니다! 확실히 잘못 해석했다. 특히 개별 결과 및 결과 개체와 어떻게 차별화되는지에 대해 – Thomas

관련 문제