4

다음 코드에서는 작업자의 전역 변수 변경 사항이 다른 작업자에게 반영되지 않는 샌드 박스 마스터 작업자 시스템을 만들려고합니다.인쇄 기능으로 인해 다중 처리 프로그램이 실패합니다.

이렇게하려면 작업을 만들 때마다 새 프로세스가 만들어지며 실행을 병렬로 수행하려면 프로세스 자체의 생성이 ThreadPoolExecutor으로 관리됩니다.

import time 
from concurrent.futures import ThreadPoolExecutor 
from multiprocessing import Pipe, Process 


def task(conn, arg): 
    conn.send(arg * 2) 


def isolate_fn(fn, arg): 

    def wrapped(): 
    parent_conn, child_conn = Pipe() 
    p = Process(target=fn, args=(child_conn, arg), daemon=True) 
    try: 
     p.start() 
     r = parent_conn.recv() 
    finally: 
     p.join() 
    return r 

    return wrapped 


def main(): 
    with ThreadPoolExecutor(max_workers=4) as executor: 
    pair = [] 

    for i in range(0, 10): 
     pair.append((i, executor.submit(isolate_fn(task, i)))) 

     # This function makes the program broken. 
     # 
     print('foo') 

    time.sleep(2) 

    for arg, future in pair: 
     if future.done(): 
     print('arg: {}, res: {}'.format(arg, future.result())) 
     else: 
     print('not finished: {}'.format(arg)) 

    print('finished') 

main() 

이 프로그램은 루프 내에 print('foo') 함수를 넣을 때까지 정상적으로 작동합니다. 함수가 존재하면, 일부 태스크는 미완성 상태로 남아 있으며, 더 나쁜 것은이 프로그램 자체가 완료되지 않습니다.

결과는 항상 동일하지 않습니다,하지만 다음은 전형적인 출력 :

foo 
foo 
foo 
foo 
foo 
foo 
foo 
foo 
foo 
foo 
arg: 0, res: 0 
arg: 1, res: 2 
arg: 2, res: 4 
not finished: 3 
not finished: 4 
not finished: 5 
not finished: 6 
not finished: 7 
not finished: 8 
not finished: 9 

왜이 프로그램이 너무 약해?

저는 파이썬 3.4.5를 사용합니다.

답변

1

시도는 파이썬 멀티에 대한 유래를 검색하는 경우

from multiprocessing import set_start_method 

... rest of your code here .... 

if __name__ == '__main__': 
    set_start_method('spawn') 
    main() 

를 사용하여 비슷한 매달려 문제를 언급 A A 공정한 몇 가지 질문을 찾을 멀티 스레딩. (python 버전 2.7 및 3.2의 경우)

멀티 스레딩과 멀티 프로세싱을 함께 사용하면 여전히 문제가 발생하지 않으며 심지어 multiprocessing.set_start_method에 대한 python 문서도 언급됩니다. 귀하의 경우 '스폰''forkserver'은 문제없이 작동해야합니다.

또 다른 옵션은 MultiProcessingPool을 직접 사용하는 것일 수 있지만 더 복잡한 사용 예에서는 가능하지 않을 수 있습니다.

btw. '완료되지 않음'은 하위 프로세스가 끝날 때까지 기다리지 않아도 출력에 나타날 수 있지만 전체 코드가 더 이상 멈추지 않고 항상 정상적으로 완료되어야합니다.

0

매 반복마다 미리 초기화 된 풀을 사용하는 대신 ThreadPoolExecutor를 매번 생성하지 않습니다. 나는 정말로 당신을 방해하고있는 인쇄 진술을 추적 할 수 없다?

+0

감사합니다. 인쇄 기능을 명확히했습니다. –

관련 문제