C에서 waitpid 함수 사용

Jinku Hu 2023년10월12일
  1. waitpid함수를 사용하여 C에서 하위 프로세스 상태 모니터링
  2. 매크로를 사용하여 C에서 자식 프로세스의 대기 상태 표시
C에서 waitpid 함수 사용

이 기사는 C에서waitpid함수를 사용하는 방법에 대한 여러 방법을 보여줍니다.

waitpid함수를 사용하여 C에서 하위 프로세스 상태 모니터링

Unix 기반 시스템에는 단순히 프로그램의 실행 인스턴스 인 프로세스라는 개념이 있습니다. 프로세스는fork시스템 호출을 사용하여 다른 프로세스를 생성하고 코드의 주어진 부분을 실행할 수 있습니다. 이 항목에서 시스템 호출은 C 스타일 함수로 사용자에게 제공되는 운영 체제 서비스입니다. 일반적으로 많은 시나리오에서 자식이라고하는 자신이 만든 프로세스를 모니터링하는 프로그램이 필요합니다. wait기능 군은이 기능을 제공하는 것이고waitpid는 그 중 하나입니다.

wait시스템 호출에는 여러 가지 제한 사항이 있으며 더 고급 기능을 다루려면waitpid기능을 사용해야합니다. 즉, 프로세스가 여러 자식을 만들고 부모가 특정 자식을 모니터링해야하는 경우waitpid만이를 수행 할 수 있습니다. 다음 예에서는 새 자식 프로세스를 만들고 다른 프로그램을 실행하는spawnChild라는 함수를 구현합니다. 예제의 좋은 데모를 위해 사용자가 종료 할 때까지 실행되는top프로그램 (거의 모든 Unix 기반 시스템에서 사용 가능)을 실행합니다. 함수가 부모 프로세스로 돌아 오면 자식 프로세스 ID를 저장하고이를waitpid함수에 전달하여 상태를 모니터링합니다.

waitpid는 세 개의 인수를 취하며 그 중 첫 번째는 프로세스 ID 번호 (pid)입니다. PID는 서로 다른 효과로 미리 지정된 값을 여러 개 가질 수 있지만이 경우-1> 0만 언급합니다. -1값은wait기능을 구현하는 데 사용되는 상태를 먼저 변경하는 하위 프로세스를 모니터링하기 위해 전달 될 수 있습니다. > 0은 값이fork함수에서 리턴 된 실제 프로세스 ID 여야 함을 의미하며 이는 차례로 특정 하위 프로세스 만 모니터링하는 데 사용됩니다. 두 번째 인수는int포인터 유형이며 정수 변수를 선언하여 해당 주소를 함수에 전달해야합니다. 반면에waitpid는 지정된int변수에 하위 상태 정보를 저장하며 사전 정의 된 매크로를 사용하여 디코딩 할 수 있습니다. 마지막 인수는int유형이며 기본 이벤트 외에 모니터링 할 특정 하위 프로세스 이벤트를 지정하는 데 사용됩니다.

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

pid_t spawnChild(const char* program, char** arg_list) {
  pid_t ch_pid = fork();
  if (ch_pid == -1) {
    perror("fork");
    exit(EXIT_FAILURE);
  }

  if (ch_pid > 0) {
    printf("spawn child with pid - %d\n", ch_pid);
    return ch_pid;
  } else {
    execvp(program, arg_list);
    perror("execve");
    exit(EXIT_FAILURE);
  }
}

int main(void) {
  const char* args[] = {"top", NULL, NULL};

  pid_t child;
  int wstatus;

  child = spawnChild("top", args);

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

  exit(EXIT_SUCCESS);
}

매크로를 사용하여 C에서 자식 프로세스의 대기 상태 표시

waitpid함수가 호출되면 상위 프로세스가 일시 중단되고 모니터링되는 하위 프로세스가 상태를 변경할 때까지 실행을 재개하지 않습니다. 다음 예제는WUNTRACEDWCONTINUED인수가있는waitpid호출을 보여줍니다. 이는 상위가 하위가 해당 신호에 의해 중지되었거나 계속되는지 여부를 모니터 함을 의미합니다. 또한 검색된 자식 상태를 인쇄하기 위해 호출 할 수있는printWaitStatus함수를 구현했습니다. <sys / wait.h>헤더에 정의 된W *유형 매크로를 사용하여status정수 변수에서 인코딩 된 정보를 추출합니다.

모든 매크로를 모든 플랫폼에서 사용할 수있는 것은 아니므로 일부 조건부 전 처리기 정의가 있으므로 함수가 이식 가능하고 상관없이 성공적으로 컴파일됩니다.

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

pid_t spawnChild(const char* program, char** arg_list) {
  pid_t ch_pid = fork();
  if (ch_pid == -1) {
    perror("fork");
    exit(EXIT_FAILURE);
  }

  if (ch_pid > 0) {
    printf("spawn child with pid - %d\n", ch_pid);
    return ch_pid;
  } else {
    execvp(program, arg_list);
    perror("execve");
    exit(EXIT_FAILURE);
  }
}

void printWaitStatus(int status) {
  if (WIFEXITED(status)) {
    printf("child exited, status=%d\n", WEXITSTATUS(status));
  } else if (WIFSIGNALED(status)) {
    printf("child killed by signal %d (%s)", WTERMSIG(status),
           strsignal(WTERMSIG(status)));
#ifdef WCOREDUMP
    if (WCOREDUMP(status)) printf(" (core dumped)");
#endif
    printf("\n");
  } else if (WIFSTOPPED(status)) {
    printf("child stopped by signal %d (%s)\n", WSTOPSIG(status),
           strsignal(WSTOPSIG(status)));
#ifdef WIFCONTINUED
  } else if (WIFCONTINUED(status)) {
    printf("child continued\n");
#endif
  } else {
    printf("status=%x\n", (unsigned int)status);
  }
}

int main(void) {
  const char* args[] = {"top", NULL, NULL};

  pid_t child;
  int wstatus;

  child = spawnChild("top", args);

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

  printWaitStatus(wstatus);

  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