C에서 자식 프로세스 죽이기

Jinku Hu 2023년10월12일
  1. SIGKILL신호를 사용하여 C에서 하위 프로세스 종료
  2. SIGTERM신호를 사용하여 C에서 하위 프로세스 종료
C에서 자식 프로세스 죽이기

이 기사는 C에서 자식 프로세스를 종료하는 방법에 대한 여러 가지 방법을 보여줍니다.

SIGKILL신호를 사용하여 C에서 하위 프로세스 종료

전달시 프로세스를 종료하도록 설계된 여러 신호가 있지만SIGKILL신호를 보내는 것이 가장 강력하고 확실한 방법입니다. 일반적으로 프로그램은 해당 신호가 프로그램에 전달되면 자동으로 호출되는 신호 핸들러라는 특수 함수를 등록 할 수 있습니다. 사용자는 일반적으로 프로그램에 대한 일부 정리 작업을 수행하는 핸들러 함수 코드를 구현합니다. 함수 핸들러 외에도 차단 및 무시와 같은 전달 된 신호에 대한 기본 작업이있을 수 있습니다. 그러나SIGKILL신호는 주어진 함수에 의해 무시, 차단 또는 처리 될 수 없습니다. 따라서이 방법은 프로세스를 종료 할 때 최후의 수단이되어야합니다.

SIGKILL신호는kill시스템 호출로 전송 될 수 있습니다. 그러나 다음 코드 샘플에 등록 된SIGTERM핸들러는 전달 된SIGKILL을 포착 할 수 없으며 주어진 하위 프로세스를 즉시 종료합니다.

다음 프로그램은 자식 프로세스를 생성하고 그 안에SIGTERM핸들러를 등록합니다. 그런 다음 하위 프로세스는 신호가 전달되지 않는 한 무한 루프를 실행하여while표현식 변수를 뒤집습니다. 결과적으로 부모가 전달한SIGKILL신호는 핸들러를 호출하지 않고 자식 프로세스를 즉시 종료합니다.

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

volatile sig_atomic_t shutdown_flag = 1;

void cleanupRoutine(int signal_number) { shutdown_flag = 0; }

int main(void) {
  int wstatus;

  pid_t c_pid = fork();
  if (c_pid == -1) {
    perror("fork");
    exit(EXIT_FAILURE);
  }

  if (c_pid == 0) {
    printf("printed from child process - %d\n", getpid());

    int count = 0;

    struct sigaction sigterm_action;
    memset(&sigterm_action, 0, sizeof(sigterm_action));
    sigterm_action.sa_handler = &cleanupRoutine;
    sigterm_action.sa_flags = 0;

    // Mask other signals from interrupting SIGTERM handler
    if (sigfillset(&sigterm_action.sa_mask) != 0) {
      perror("sigfillset");
      exit(EXIT_FAILURE);
    }
    // Register SIGTERM handler
    if (sigaction(SIGTERM, &sigterm_action, NULL) != 0) {
      perror("sigaction SIGTERM");
      exit(EXIT_FAILURE);
    }

    while (shutdown_flag) {
      count += 1;
    }
    printf("count = %d\n", count);

    exit(EXIT_SUCCESS);
  } else {
    printf("printed from parent process - %d\n", getpid());
    int ret;

    sleep(5);

    ret = kill(c_pid, SIGKILL);
    if (ret == -1) {
      perror("kill");
      exit(EXIT_FAILURE);
    }

    if (waitpid(c_pid, &wstatus, WUNTRACED | WCONTINUED) == -1) {
      perror("waitpid");
      exit(EXIT_FAILURE);
    }
  }

  exit(EXIT_SUCCESS);
}

SIGTERM신호를 사용하여 C에서 하위 프로세스 종료

또는 프로그램에서 처리 할 수있는SIGTERM신호를 사용하여 하위 프로세스를 종료 할 수 있습니다. 다음 코드 샘플은SIGKILL신호를SIGTERM으로 대체한다는 점을 제외하고 이전 프로그램 구현을 반복합니다. sigfillset함수는 다른 신호가 등록 된 핸들러 함수 실행을 방해하는 것을 방지하는 데 사용됩니다. 핸들러 코드는 하위 프로세스에서while루프를 중지하고count변수의 값을 인쇄하는 전역sig_atomic_t유형 변수를 수정합니다. 하지만 핸들러를 등록 할 때signal함수 위에sigaction호출을 사용하는 것이 항상 더 좋습니다. 후자는 POSIX 표준에 의해 자세히 지정되어 있지 않기 때문입니다.

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

volatile sig_atomic_t shutdown_flag = 1;

void cleanupRoutine(int signal_number) { shutdown_flag = 0; }

int main(void) {
  int wstatus;

  pid_t c_pid = fork();
  if (c_pid == -1) {
    perror("fork");
    exit(EXIT_FAILURE);
  }

  if (c_pid == 0) {
    printf("printed from child process - %d\n", getpid());

    int count = 0;
    struct sigaction sigterm_action;
    memset(&sigterm_action, 0, sizeof(sigterm_action));
    sigterm_action.sa_handler = &cleanupRoutine;
    sigterm_action.sa_flags = 0;

    // Mask other signals from interrupting SIGTERM handler
    if (sigfillset(&sigterm_action.sa_mask) != 0) {
      perror("sigfillset");
      exit(EXIT_FAILURE);
    }
    // Register SIGTERM handler
    if (sigaction(SIGTERM, &sigterm_action, NULL) != 0) {
      perror("sigaction SIGTERM");
      exit(EXIT_FAILURE);
    }

    while (shutdown_flag) {
      count += 1;
    }
    printf("count = %d\n", count);

    exit(EXIT_SUCCESS);
  } else {
    printf("printed from parent process - %d\n", getpid());
    int ret;

    sleep(5);

    ret = kill(c_pid, SIGTERM);
    if (ret == -1) {
      perror("kill");
      exit(EXIT_FAILURE);
    }

    if (waitpid(c_pid, &wstatus, WUNTRACED | WCONTINUED) == -1) {
      perror("waitpid");
      exit(EXIT_FAILURE);
    }
  }

  exit(EXIT_SUCCESS);
}
작가: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

관련 문장 - C Process