0

python3의 multiprocess에서 __del__ 메서드를 호출 할 수 없습니다.__del__ 메서드가 호출되지 않는 이유

순환 참조에 대한 다른 문제를 읽었지만 multiprocess에서 상황을 찾을 수 없습니다.

foo 직접 호출 될 때 foo에, __del__가 호출됩니다 순환 참조는하지만, multiprocess__del__가 호출되지 않습니다.

import multiprocessing 
import weakref 


class Foo(): 
    def __init__(self): 
     self.b = [] 

    def __del__(self): 
     print ('del') 


def foo(): 
    print ('call foo') 
    f = Foo() 
    a = [f] 
    # a = [weakref.ref(f)] 
    f.b.append(a) 


# call foo in other process 
p = multiprocessing.Process(target=foo) 
p.start() 
p.join() 


# call foo 
foo() 

출력 :
전화 foo는
전화 foo는
__del__p에서 호출되지 않는 이유

?

+0

'약점'은 무엇이라고 생각하십니까? 코드에서 언급하고이 질문과 관련되어 있지만 관련성이 있다고 생각하는 이유는 밝히지 않았습니다. –

답변

1

갈래 Process 객체는 출구에없이 정상 정리 파이썬 수행을 강제로 자식 프로세스 을 종료 os._exit()를 사용하여 작업을 실행 한 후 종료합니다. 주기적인 쓰레기는 청소되지 않습니다 (프로세스가 순환 GC에 실행 기회를주지 않고 종료되기 때문에), 바닥에 떨어 뜨려 OS를 정리합니다.

정상적으로 종료하면 (정상적인 모든 정리 절차를 호출하면) 부모와 자식 모두에서 플러시되지 않은 버퍼가 플러시되고 (출력이 두 배로 늘어남) 포크 프로세스가 모든 상태를 상속받을 때 위험이 따릅니다. 부모가 명시 적으로 그렇게하도록 지시 할 때를 제외하고는 그것을 사용하지 않아야합니다.

1

문제가 multiprocess에서 호출없는 이유 사실은 아니지만, 다른 예에서 호출 이유. 그리고 그 대답은 foo에 전화 할 때 호출되지 않는다는 것입니다. 프로그램이 끝날 때 호출됩니다. 프로그램이 끝났기 때문에, 파이썬은 참조 된 경우라도 다른 것이 정리 될 수 있음을 알고 있으므로 순환 참조를 정리합니다.

스크립트의 끝에 print 문을 추가하거나, REPL에서이를 호출 할 경우, 당신은 __del__ 여전히 두 번째 foo 전화에 호출되지 것을 볼 수 있지만 스크립트의 끝 부분에 있습니다.

스크립트가 끝날 때 파이썬이 순환 참조를 정리한다고 가정하면 ShadowRanger's answer은 다중 처리 기능이 끝났을 때 발생하지 않는 이유를 설명합니다.

+0

Python은 스크립트 종료시가 아니라 순환 참조를 간헐적으로 정리합니다. 대부분의 세부 사항은 [gc 모듈] (https://docs.python.org/3/library/gc.html)에 문서화되어 있지만, 짧은 버전은 모니터 참조의 풀을 보존하고 유지 보수하며 새로운 풀은보다 빈번하게, 그리고 오래된 풀은보다 적은 빈도로 수행되며, 간격은 수행 된 할당 및 할당 취소 횟수에 의해 결정됩니다. 즉, 라이브 (비 주기적) 참조가 존재하는 한 순환 수집은 중요하지 않습니다 (주기적 쓰레기가 아니기 때문에). – ShadowRanger

+0

나는 그때만이 일어났다 고 말하지 않도록주의를 기울 였지만, 나는 그것을 암시했다.나는 잘 모르겠다. 그러나 나는 보통 그때 만 일어난다 고 생각했다. 그러나 당신이 원한다면 당신이'gc'에서 부를 수있는 것이 있거나 아마도 당신이 기억이 나쁘다면 아마 체크했다. 그것은 가끔 어쨌든 끝나기 전에 때때로 일어나는 것을 아는 것이 좋습니다. –

관련 문제