C에서 프로세스에 신호 보내기

Jinku Hu 2023년10월12일
  1. kill기능을 사용하여 C의 프로세스에 신호 보내기
  2. kill함수 및 Null 신호를 사용하여 C에서 프로세스의 존재 여부 확인
C에서 프로세스에 신호 보내기

이 기사에서는 C에서 프로세스에 신호를 보내는 방법에 대한 몇 가지 방법을 설명합니다.

kill기능을 사용하여 C의 프로세스에 신호 보내기

신호는 특정 이벤트를 표시 할 수있는 인터럽트 스타일 알림이며 프로세스로 전송 될 수 있습니다. 첫 번째 프로세스에 올바른 권한이있는 경우 한 프로세스가 다른 프로세스에 신호를 보낼 수 있습니다. 신호는 다른 프로그램, 자식 ​​프로세스 또는 스레드와 상호 작용하는 데 사용할 수있는 프로세스 간 통신 유형입니다. kill기능을 사용하여 다양한 신호를 프로세스에 보낼 수 있습니다. 전달 될 프로세스 ID와 신호 번호의 두 가지 인수가 필요합니다. 신호 번호는SIG___유형 매크로로 정의 된 상수 정수입니다.

다음 예에서는fork호출을 사용하여 자식 프로세스를 생성 한 다음 정수를 증가시키는 무한 루프를 실행하는 프로그램을 보여줍니다. 한편, 상위 프로세스는 하위 프로세스를 종료하는SIGTERM신호를 발행하고,waitpid호출을 사용하여 하위 상태 코드를 수신 한 후 기본 기능이 종료됩니다.

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

int main(int argc, char *argv[]) {
  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;

    while (1) {
      count += 1;
    }

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

    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);
}

kill함수 및 Null 신호를 사용하여 C에서 프로세스의 존재 여부 확인

kill기능의 또 다른 사용 사례는 프로세스의 존재를 확인하는 것입니다. 이 방법으로 일부 프로세스의 존재를 확인하려고해도 검색된 상태가 올바르지 않은 시나리오가있을 수 있습니다. 이는 관찰 된 프로세스가 이미 종료되고 운영 체제에서 식별 번호를 재사용 할 수 있기 때문에 다른 프로그램이 동일한 ID를 사용하고있을 때 발생할 수 있습니다.

kill에는 신호 번호 (0)가 전달되어야하며 함수의 반환 코드에서 errno코드를 테스트해야합니다. 즉, kill-1오류 코드를 반환하고 errnoESRCH로 설정되면 주어진 프로세스가 존재하지 않습니다. errnoEPERM값과 함께 오류 코드가 반환되는 경우-프로그램이 존재하지만 호출자 프로세스에 신호를 보낼 권한이 없습니다. 0이 반환되는 경우 프로세스가 존재하고 호출자 프로세스가 다른 신호를 보낼 수 있습니다.

다음 코드 샘플은 위의 상태 확인 문을 구현하고 해당 메시지를 인쇄합니다.

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

int main(int argc, char *argv[]) {
  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 = 10;

    while (count >= 0) {
      count -= 1;
      sleep(1);
    }

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

    errno = 0;
    ret = kill(c_pid, 0);
    if (ret == -1) {
      if (errno == EPERM)
        printf(
            "Process exists, but we don't have "
            "permission to send it a signal\n");
      else if (errno == ESRCH)
        printf("Process does not exist\n");
      else
        perror("kill");
      exit(EXIT_FAILURE);
    } else {
      printf("Process exists and we can send it a signal\n");
    }

    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 Signal