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
함수가 호출되면 상위 프로세스가 일시 중단되고 모니터링되는 하위 프로세스가 상태를 변경할 때까지 실행을 재개하지 않습니다. 다음 예제는WUNTRACED
및WCONTINUED
인수가있는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);
}
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