2017-02-19 8 views
0

URL에서 다운로드 HTML과 같은 작업을 수행하는 함수 목록이 있습니다 (각 함수는 매우 다르므로 URL과 downlaod를 수락 할 단일 함수를 만들 수 없습니다). 나는 작업 속도를 높이기 위해 다중 처리를 사용했다. 아래는 내 코드입니다파이썬 다중 처리 콜백

def runInParallel(list_of_functions): 
    for fn in list_of_functions: 
    proc = [Process(target=fn[1]).start() for fn in list_of_functions] 
    for p in proc: 
    p.join() 

각 기능이 반환하는 결과를 저장하는 방법은 무엇입니까? 각 함수는 데이터베이스에 구문 분석하고 저장해야하는 dict을 반환하며 각 함수에서 이러한 단계를 반복하지 않으므로 fucntions에서 반환 된 결과와 함께 전달 될 수있는 일종의 콜백입니다. 어떻게 할 수 있습니까?

편집 : pool을 사용하지만 오류가 발생합니다. 나는 list_of_functions에 대해 다음 한 : 위의 설명에서 언급 한 바와 같이

[('f1', <function f1 at 0x7f34c11c9ed8>), ('f2', <function f2 at 0x7f34c11c9f50>)] 


def runInParallel(list_of_functions): 
    import multiprocessing 
    pool = multiprocessing.Pool(processes = 3) 
    x = pool.map(lambda f: f(), list_of_functions) 
    print x 




File "main.py", line 31, in <module> 
    runInParallel(all_functions) 
    File "main.py", line 11, in runInParallel 
    x = pool.map(lambda f: f(), list_of_functions) 
    File "/usr/lib/python2.7/multiprocessing/pool.py", line 251, in map 
    return self.map_async(func, iterable, chunksize).get() 
    File "/usr/lib/python2.7/multiprocessing/pool.py", line 558, in get 
    raise self._value 
cPickle.PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed 
+0

[다중 처리에서 반환 값을 얻을 수 있습니까?] (http://stackoverflow.com/questions/8329974/can-i-) 리턴 값 - 멀티 프로세싱 - pr ocess) – DavidW

+0

참조 http://stackoverflow.com/questions/10415028/how-can-i-recover-the-return-value-of-a-function-passed-to-multi 및 http://stackoverflow.com/question/10797998/python을 반환하는 -ex-it-possible-to-multiprocess-a-function – DavidW

+0

@DavidW는 응답을 주셔서 감사합니다. 그러나 어떻게하면 mc에 대해 results = [result_queue.get() in montecarlos]'내 코드에서? – anekix

답변

0

: 직접 Process를 사용하는 경우는, 어디 프로세스 put에 큐를 설정해야하므로 부모 프로세스로부터 get 할 수 있습니다

from multiprocessing import Process, Queue 
from time import sleep 

def f1(queue): 
    sleep(1) # get url, "simulated" by sleep 
    queue.put(dict(iam="type 1")) 

def f2(queue): 
    sleep(1.5) 
    queue.put(dict(iam="type 2")) 

def f3(queue): 
    sleep(0.5) 
    queue.put(dict(iam="type 3")) 


def runInParallel(list_of_functions): 
    queue = Queue() 
    for fn in list_of_functions: 
     proc = [Process(target=fn[1], args=(queue,)) for fn in list_of_functions] 
    for p in proc: 
     p.start() 
    res = [] 
    for p in proc: 
     p.join() 
     res.append(queue.get()) 
    return res 

if __name__ == '__main__': 
    list_of_functions = [("f1", f1), ("f2", f2), ("f3", f3)] 
    for d in runInParallel(list_of_functions): 
     print d 

인쇄 :

{'iam': 'type 3'} 
{'iam': 'type f1'} 
{'iam': 'type f2'} 

당신의 기능은 기본적으로 할 경우 모두 같은 (가져 오는 URL 및 공정

from multiprocessing import Pool 
from time import sleep 

def f(arg): 
    url, typ = arg 
    if typ == 'a': 
     sleep(1) # instead you would do something with `url` here 
     return dict(iam="type 1", url=url) 
    elif typ == 'b': 
     sleep(1.5) 
     return dict(iam="type 2", url=url) 
    elif typ == 'c': 
     sleep(0.5) 
     return dict(iam="type 3", url=url) 

def runInParallel(work): 
    p = Pool(3) 
    return p.map(f, work) 

if __name__ == '__main__': 
    work = [('http://url1', 'a'), 
     ('http://url2', 'b'), 
     ('http://url3', 'c'), 
     ] 
    for d in runInParallel(work): 
     print d 

인쇄 :

{'url': 'http://url1', 'iam': 'type 1'} 
{'url': 'http://url2', 'iam': 'type 2'} 
{'url': 'http://url3', 'iam': 'type 3'} 

두 스크립트를 다음 몇 가지 if/elif 로직을 하나에 당신의 기능을 병합 어떤 방법으로 HTML)를, 당신이 map을 사용하고 당신이 어떤 큐를 필요로하지 않을 수 있습니다 Unix 환경에서와 같이 Windows에서 작동합니다 (OSX에서 시도).