본문 바로가기
코딩취미/Python

PySide6 프로그램 종료 시 반드시 호출되는 함수는 있을까?

by 브링블링 2025. 4. 21.
반응형

PySide6 프로그램 종료 시 반드시 호출되는 함수는 있을까?

PySide6로 GUI 프로그램을 개발하다 보면 프로그램이 종료될 때 어떤 처리를 확실히 해줘야 할 상황이 자주 발생합니다.
예를 들어, 사용자 설정 저장, 로그 기록, 자원 정리 등은 종료 직전에 반드시 처리되어야 하는 작업입니다. 

 

그렇다면 PySide6에서 프로그램이 종료될 때 반드시 호출되는 함수는 있을까요?

아쉽게도 결론은 "무조건 호출되는 함수는 없다" 입니다.

 

하지만 종료 상황에 따라 다양한 우회 방법을 통해 대부분의 케이스를 커버할 수 있습니다.


1. 정상 종료 대응 방법

✅ atexit 모듈 사용

정상적으로 종료되는 경우에 호출됩니다.

import atexit

def cleanup():
    print("정상 종료 시 호출됩니다.")

atexit.register(cleanup)

✅ QCoreApplication.aboutToQuit 시그널

Qt 애플리케이션이 종료되기 직전에 발생하는 시그널입니다.

from PySide6.QtWidgets import QApplication

app = QApplication([])

def on_exit():
    print("aboutToQuit 시그널로 종료 처리")

app.aboutToQuit.connect(on_exit)

2. 예외 발생 또는 에러 종료 대응

✅ try...except...finally 구조

import sys
from PySide6.QtWidgets import QApplication

try:
    app = QApplication(sys.argv)
    # 프로그램 실행
    sys.exit(app.exec())
except Exception as e:
    print(f"예외 발생: {e}")
finally:
    print("종료 직전 cleanup 처리")
 

finally는 예외가 발생하더라도 호출됩니다.
단, C++에서 발생하는 심각한 오류는 제외됩니다.


3. 운영체제 시그널 처리

✅ signal 모듈로 SIGINT, SIGTERM 대응

import signal
import sys

def handle_signal(signum, frame):
    print(f"Signal {signum} 수신됨. 종료 처리 수행.")
    sys.exit(0)

signal.signal(signal.SIGINT, handle_signal)   # Ctrl+C
signal.signal(signal.SIGTERM, handle_signal)  # kill PID

4. 치명적 오류 (segfault, SIGSEGV) 대응

⚠️ faulthandler 모듈 활용

import faulthandler

faulthandler.enable()
# 또는 로그 파일로 저장
faulthandler.register(signal.SIGSEGV, file=open("fault.log", "w"))
 

세그멘테이션 폴트가 발생할 경우 트레이스백을 출력해 디버깅에 도움을 줄 수 있습니다.

반응형

5. 감시자(Watchdog) 프로세스로 보완

프로그램이 갑자기 꺼지는 상황까지 감지하려면, 메인 앱을 감시하는 별도 감시 프로세스를 두는 방식이 있습니다.

import subprocess
import time

while True:
    print("GUI 앱 실행 중...")
    proc = subprocess.Popen(["python", "my_gui_app.py"])
    proc.wait()
    print("앱 종료 감지. 후처리 수행...")
    time.sleep(1)
 

이 방식은 비정상 종료 시에도 재시작하거나 로그를 남기는 등의 대응이 가능합니다.


✅ 종료 상황별 처리 가능성 요약표

종료 상황 처리 가능성 방법
sys.exit(), 창 닫기 atexit, aboutToQuit
Ctrl+C (SIGINT) signal.signal()
kill PID (SIGTERM) signal.signal()
kill -9 (SIGKILL) (불가능)
segmentation fault ⚠️ (제한적) faulthandler, 감시 프로세스
시스템 전원 강제 종료 (불가능)

💡 팁: 종료 처리는 "여러 계층에서 조합"해야 한다

  1. atexit, aboutToQuit, finally 로 대부분의 정상 종료를 처리
  2. signal로 OS 수준의 종료 신호에 대응
  3. faulthandler로 치명적 오류 감지 및 로그 출력
  4. 중요 상태는 종료 직전이 아니라 주기적으로 저장하는 구조 설계
  5. 반드시 지켜야 할 처리는 감시 프로세스를 통해 보완
반응형