1

나는 다음과 같은 시도하고있다 :파이썬 다중 처리 : 객체가 값으로 전달 되었습니까?

from multiprocessing import Pool 

def f(some_list): 
    some_list.append(4) 
    print 'Child process: new list = ' + str(some_list) 
    return True 

if __name__ == '__main__': 

    my_list = [1, 2, 3] 
    pool = Pool(processes=4) 
    result = pool.apply_async(f, [my_list]) 
    result.get() 

    print 'Parent process: new list = ' + str(my_list) 

내가 무엇을 얻을 :

Child process: new list = [1, 2, 3, 4] 
Parent process: new list = [1, 2, 3] 

그래서, 그것은 돌연변이하지 않았다 이후 을 my_list이 값에 의해 전달 된 것을 의미한다. 그래서 다른 프로세스로 넘어갈 때 실제로 값으로 전달된다는 규칙이 있습니까? 감사합니다. .

답변

4

André Laszlo가 말한 것처럼 multiprocessing 라이브러리는 multiprocessing.Pool 메서드로 전달 된 모든 개체를 피벗 처리하여 작업자 프로세스로 전달해야합니다. 산세 프로세스로 인해 작업자 프로세스에서 별개의 개체가 만들어 지므로 작업자 프로세스에서 해당 개체의 변경 사항이 부모 개체에 영향을 미치지 않습니다. 리눅스에서는 객체가 fork 상속 (예 : multiprocessing.Process(target=func, args=(my_list,)))을 통해 자식 프로세스로 전달되는 경우가 있지만이 경우 자식 프로세스에서 객체의 복사시 복사 버전이되므로 최종 사본이 남습니다 두 프로세스 중 하나에서 수정할 때.

당신이 프로세스간에 개체를 공유 할 경우, 해당위한 multiprocessing.Manager 사용할 수 있습니다

from multiprocessing import Pool, Manager 

def f(some_list): 
    some_list.append(4) 
    print 'Child process: new list = ' + str(some_list) 
    return True 

if __name__ == '__main__': 

    my_list = [1, 2, 3] 
    m = Manager() 
    my_shared_list = m.list(my_list) 
    pool = Pool(processes=4) 
    result = pool.apply_async(f, [my_shared_list]) 
    result.get() 

    print 'Parent process: new list = ' + str(my_shared_list) 

출력 : 당신이 위의 "실"의 모든 인스턴스를 교체해야

Child process: new list = [1, 2, 3, 4] 
Parent process: new list = [1, 2, 3, 4] 
+0

감사합니다. f 함수가 수정 된 객체를 반환하도록하면 어떻게 될까요? Manager를 사용하는 것과 비교할 때 효율성이 많이 떨어질까요? – jazzblue

+1

@jazzblue 유스 케이스를 사용하여 자식의 목록을 수정하고 부모에게 반환 할 수있게하려면 'Manager'대신 해당 목록을 사용하십시오. 'Manager' 객체를 사용하면 공유 목록에 액세스 할 때마다 실제로'Manager' 프로세스에 IPC 호출을합니다. 이것은 목록에 기본적으로 액세스하는 것보다 훨씬 느립니다. 객체를 부모에게 반환하면 프로세스간에 목록 객체를 전달하는 일회성 IPC 히트를 취하지 만 거대한 목록을 다루지 않는 한 모든 객체의 비용을 능가하지는 않을 것입니다 IPC는 공유 목록에 필요합니다. – dano

3

multiprocessing 라이브러리는 pickle을 사용하여 개체를 직렬화하여 프로세스간에 전달합니다.

이렇게하면 안전한 프로세스 간 통신을 보장 할 수 있으며 두 프로세스가 공유 메모리를 사용하지 않고 "동일한"개체를 사용할 수 있습니다.

+1

"를 방법". – dano

+0

물론, 내 나쁜! –

관련 문제