[python] signal

About_work·2024년 2월 28일
0

python 기초

목록 보기
41/65

1. 언제 쓰는가?

  • 아래 시그널들이 발생했을 때, 실시할 로직을 만들기 위함!
  • 대표적으로는
    • 사용자가 ctrl+c 로 프로그램을 종료하여 발생하는 시그널
    • 현재 터미널 세션과 연관된 포어그라운드 프로세스 그룹에 있는 프로세스가 종료되는 경우 발생하는 시그널

2. 예시

import signal

def graceful_exit(realsense_components: List[base.Base],
                  total_shm_info: shared_memory.TotalShmInfo):
    """graceful_exit routine to stop all components and release resources."""
    for component in realsense_components:
        try:
            component.graceful_exit()
        except Exception as e:
            print(f"Error stopping {component}: {e}")
    total_shm_info.graceful_exit()

if __name__ == '__main__':

    def signal_handler(sig: int, frame: Optional[FrameType]) -> None:
        # 외부 인터럽트에 대응.
        print("시그널 받음, 우아하게 종료 중...")
        graceful_exit(realsense_components, total_shm_info)
        # 프로그램을 성공적으로 종료합니다. 0은 일반적으로 성공을 의미하는 종료 코드
        exit(0)
    # SIGINT: 인터럽트 시그널. 사용자가 프로그램을 종료하는 경우 발생
    signal.signal(signal.SIGINT, signal_handler)
    # SIGTERM: 프로세스 종료 시그널. 프로세스가 종료되는 경우 발생
    signal.signal(signal.SIGTERM, signal_handler)

3. 특징

  • 멀티스레드 환경에서는 주 스레드만 신호를 받을 수 있습니다.
    • 운영 체제는 신호를 프로세스 단위로 전달
    • 이는 신호가 특정 스레드에게 직접 전달되는 것이 아니라, 프로세스를 대표하는 주 스레드에게 전달된다는 의미
    • 여기서 "주 스레드"란 프로세스가 시작될 때 생성되는 초기 스레드를 의미
  • 아래는 여러 signal 종류를 나타냅니다. 주로 UNIX 및 UNIX 계열 시스템(Linux, macOS 등)에서 사용됩니다. Windows에서는 제한적인 신호만 사용할 수 있습니다.
  • 참고 (포어그라운드 vs 백그라운드 프로세스)

4. signal이 전달되는 범위

  • SIGINT와 같은 신호의 전달 방식은 아래 요소에 따라 달라집니다.
    • 운영 체제
    • 프로세스의 구성,
    • 프로세스가 실행되는 방식

4.1. 신호의 전달

  • 신호는 보통 현재 터미널 세션과 연관된 포어그라운드 프로세스 그룹에 전송
    • 그룹 내의 모든 프로세스는 이 신호를 받게 되며, 기본적으로는 이 신호를 받았을 때 종료

4.2. 포어그라운드 vs. 백그라운드 프로세스

  • 포어그라운드 프로세스:
    • 사용자 입력과 직접 상호작용하는 프로세스로, 터미널 세션에 바인딩
    • SIGINT와 같은 신호는, 주로 이러한 포어그라운드 프로세스에 영향을 줌
  • 백그라운드 프로세스:
    • 사용자와 직접 상호작용하지 않고 백그라운드에서 실행되는 프로세스
    • 일반적으로 SIGINT 신호는 백그라운드 프로세스에 전송되지 않음

4.3. 프로세스 그룹과 신호

  • 운영 체제: 프로세스를 그룹으로 관리
    • 터미널 또는 쉘: 포어그라운드 프로세스 그룹을 관리
  • SIGINT 같은 신호가 발생하면, 해당 터미널 세션의 포어그라운드 프로세스 그룹에 속한 모든 프로세스에 신호가 전송
  • 이는 단일 프로세스에만 신호를 보내는 것이 아니라, 연관된 프로세스 그룹에 신호를 전송한다는 것을 의미

시그널 신호 무시하는 방법

        signal.signal(signal.SIGINT, signal.SIG_IGN)
        signal.signal(signal.SIGTERM, signal.SIG_IGN)
profile
새로운 것이 들어오면 이미 있는 것과 충돌을 시도하라.

0개의 댓글