여기에서해야 할 일은 셧다운시 계산하기보다는 명시 적으로 강력한 참조를 명시 적으로 해제하는 것입니다.
특히 모듈이 출시되면 해당 전역이 출시 될 예정이지만 모듈이 출시 될 곳은 어디에도 기록되어 있지 않습니다. 따라서 종료 할 때 개체에 대한 참조가 여전히있을 수 있습니다. 그리고, 마티 피에 터스는 지적 :
__del__()
방법이 인터프리터 종료 여전히 존재하는 객체에 대해 호출되는 것을 보장 할 수 없습니다.당신이 당신의 객체 시간에는 (비 약한) 참조가 없는지 확인 할 수있는 경우
그러나 전에 인터프리터 종료, 당신은 정리 실행을 보장 할 수 있습니다.
핸들러를 사용하여 명시 적으로 자신을 지우는 데 사용할 수 있지만, 주 모듈의 끝에서 벗어나기 전에 (또는 sys.exit
을 호출하거나 마지막 비 데몬 스레드를 종료하는 등) 명시 적으로 처리 할 수 있습니다. 가장 간단한 방법은 전체 main
함수를 사용하여 with
또는 try
/finally
에 포장하는 것입니다.
또는 더 간단히 말해 코드 정리 코드를 __del__
메서드 또는 weakref 콜백에 넣지 마십시오. with
또는 finally
또는 atexit
에 정리 코드 자체를 넣기 만하면됩니다. 다른 답변에 단 댓글에서
:
는 내가 실제로 일반적으로 타이머에 의해 개방 유지 서브 프로세스를 종료되는 일을하려고하지만, 필요있어하는 것은 핵 공격을 할 때 프로그램 종료. 별도로 다른 프로세스를 모니터하고 죽이기 위해 데몬 프로세스를 시작하기 위해 이렇게하는 유일한 "신뢰성있는"방법입니까?
이런 종류의 작업을 수행하는 일반적인 방법은 외부에서 신호를 보낼 수있는 타이머로 교체하는 것입니다. 응용 프로그램 아키텍처와 사용중인 타이머의 종류 (예 : 원자로가 타이머를 작동시키는 단일 스레드 비동기 서버 또는 OS 타이머 메시지가 타이머 대 멀티를 울리는 단일 스레드 비동기 GUI 응용 프로그램)를 모르는 경우 스레드가 어디 스레드 대 sleep
간격 사이 스레드 ... 스레드 된 응용 프로그램, 더 구체적으로 설명하기 어렵다.
한편, 하위 프로세스를 처리하는 더 간단한 방법이 있는지 살펴볼 수도 있습니다. 예를 들어, 명시 적 프로세스 그룹을 사용하고 프로세스 대신 프로세스 그룹을 종료 할 수 있습니다 (세부 사항은 매우 다르지만 Windows 및 Unix 모두에서 모든 하위 작업이 종료됩니다). 또는 서브 프로세스에 파이프를 제공하고 파이프의 다른 쪽 끝이 내려갈 때 종료해야합니까?
설명서에는 삭제 된 왼쪽 참조가 삭제 된 순서에 대한 보장도 없습니다. 실제로 CPython을 사용하는 경우 Py_Finalize
은 "임의 순서로 완료되었습니다"라고 구체적으로 말합니다.
The source은 흥미 롭습니다. 분명히 무작위로 추출한 것은 아니며 완전히 임의적 인 것도 아닙니다. 먼저 아무것도 남지 않을 때까지 GC를 수집 한 다음 GC 자체를 완료 한 다음 PyImport_Cleanup
(기본적으로는 sys.modules.clear()
)을 수행 한 다음 다른 컬렉션을 주석 처리 한 후 (이유에 대한 설명과 함께) 마지막으로 _PyImport_Fini
이는 "내부 전용"으로 정의 됨).
하지만 이것은 모듈이 실제로 객체에 대한 유일한 (비 weak) 참조를 보유하고 있고 모듈 자체와 관련된 깨지 랄 수없는 사이클이 없다고 가정 할 때 모듈은 종료시 정리됩니다. 이 객체는 객체에 대한 마지막 참조를 삭제하여 객체를 정리합니다.(물론 내장 함수, 확장 모듈 및이 시점에서 여전히 존재하는 것에 대한 직접적인 참조가있는 것은 아닙니다. 그러나 foo
을 Foo
전에 정리할 수 없기 때문에 위의 코드는 괜찮습니다.
이것은 CPython에만 해당되며 사실 CPython 3.3에만 해당됩니다. 버전에 맞는 관련 소스를 읽고 싶을 것입니다. 다시 말하면 문서에 명시 적으로 "무작위 순서대로"삭제된다는 것이 명시되어 있으므로 구현 관련 동작에 의존하고 싶지 않을 때 기대할 수 있습니다. 물론 귀하의 정리 코드의
여전히를 호출 할 보장 할 수 없습니다 . 예를 들어, 처리되지 않은 신호 (Unix에서) 또는 구조화 된 예외 (Windows에서)는 아무 것도 정리할 기회를주지 않고 인터프리터를 죽입니다. 그리고 그것을 위해 핸들러를 작성하더라도 누군가 항상 전원 코드를 가져올 수 있습니다. 따라서 완전히 견고한 디자인이 필요한 경우 저널링, 원자 적 파일 조작, 명시 적 승인과 함께 프로토콜 등을 사용하여 언제든지 정리없이 중단 할 수 있어야합니다.
당신이 실제로하고있는 일에 대해 weakref 정리 (또는, __del__')에 의존하고 싶지 않다고 생각합니다. 단단한 답을 내기가 어렵지만, 흥미로운 질문입니다. 인터프리터 파이널 라이 제이션이 실제로하는 일을 보게 해줘서 고마워. 왜냐하면 거기에는 흥미로운 것들이 있기 때문이다. – abarnert