CS/운영체제
[운영체제 OS] PROCESS API IN POSIX
두루두루두
2025. 3. 17. 17:59
목차
- 프로세스 관련 시스템 호출
- fork(), wait(), exec(), kill, ...
❑ 프로세스 생성 : fork()
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]){
printf("hello world (pid:%d)\n", (int) getpid());
int rc = fork();
if (rc < 0) { // fork failed; exit
fprintf(stderr, "fork failed\n");
exit(1);
} else if (rc == 0) { // child (new process)
printf("hello, I am child (pid:%d)\n", (int) getpid());
} else { // parent goes down this path (main)
printf("hello, I am parent of %d (pid:%d)\n", rc, (int) getpid());
}
return 0;
}
▪ 자기 자신의 주소 공간, 레지스터 등을 복사한 새 프로세스 생성
▪ 실행 결과 – non-deterministic (같은 입력을 주어도 실행할 때마다 다른 결과가 나올 수 있음)
prompt> gcc -g -Wall -o p1 p1.c
prompt> ./p1
hello world (pid:17908)
hello, I am parent of 12276 (pid:17908)
hello, I am child (pid:12276)
prompt>
prompt> ./p1
hello world (pid:14660)
hello, I am child (pid:18584)
hello, I am parent of 18584 (pid:14660)
prompt>
❑ 종료 대기: wait()
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char *argv[]){
printf("hello world (pid:%d)\n", (int) getpid());
int rc = fork();
if (rc < 0) { // fork failed; exit
fprintf(stderr, "fork failed\n");
exit(1);
} else if (rc == 0) { // child (new process)
printf("hello, I am child (pid:%d)\n", (int) getpid());
} else { // parent goes down this path (main)
int wc = wait(NULL);
printf("hello, I am parent of %d (wc:%d) (pid:%d)\n",
rc, wc, (int) getpid());
}
return 0;
}
▪ 실행 결과 - deterministic
prompt> ./p2
hello world (pid:29266)
hello, I am child (pid:29267)
hello, I am parent of 29267 (wc:29267) (pid:29266)
prompt>
❑ 프로그램 실행: exec()
▪ 확보된 주소 공간에 새 프로그램 적재하여 실행
▪ execl, execv, execlp, execvp, execle, execve
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
int main(int argc, char *argv[]){
printf("hello world (pid:%d)\n", (int) getpid());
int rc = Fork();
if (rc == 0) { // child (new process)
printf("hello, I am child (pid:%d)\n", (int) getpid());
char *myargs[3];
myargs[0] = strdup("wc"); // program: "wc" (word count)
myargs[1] = strdup("p3.c"); // argument: file to count
myargs[2] = NULL; // marks end of array
execvp(myargs[0], myargs); // runs word count
printf("this shouldn’t print out");
} else { // parent goes down this path (main)
int wc = wait(NULL);
printf("hello, I am parent of %d (wc:%d) (pid:%d)\n",
rc, wc, (int) getpid());
}
return 0;
}
▪ 실행 결과
prompt> ./p3
hello world (pid:29383)
hello, I am child (pid:29384)
29 107 1030 p3.c
hello, I am parent of 29384 (wc:29384) (pid:29383)
prompt>
❑ 입출력 재지정 (Redirection)
prompt> wc p3.c
29 107 1030 p3.c
prompt> wc p3.c > newfile.txt
prompt> cat newfile.txt
29 107 1030 p3.c
prompt> cat p3.c | wc
29 107 1030
▪ 표준 입출력도 파일로 취급 → 파일을 변경하는 효과
❑ 프로그램 내 재지정 구현
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/wait.h>
int main(int argc, char *argv[]){
int rc = fork();
if (rc < 0) { // fork failed; exit
fprintf(stderr, "fork failed\n");
exit(1);
} else if (rc == 0) { // child: redirect standard output to a file
close(STDOUT_FILENO);
open("./p4.output", O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);
// now exec "wc"...
char *myargs[3];
myargs[0] = strdup("wc"); // program: "wc" (word count)
myargs[1] = strdup("p4.c"); // argument: file to count
myargs[2] = NULL; // marks end of array
execvp(myargs[0], myargs); // runs word count
} else { // parent goes down this path (main)
int wc = wait(NULL);
}
return 0;
}
▪ 실행 결과
prompt> ./p4
prompt> cat p4.output
32 109 846 p4.c
prompt>
❑ 기타 APIs
▪ getpid(), getppid(), …
▪ 프로세스 그룹과 세션
▪ 시그널 처리: sigaction(), sigprocmask(), kill(), raise(), …
❑ Shell과 프로세스 제어
▪ 외부 명령 (kill)으로 특정 시그널 전달: SIGINT, SIGTSTP, ..
▪ 명령어로 프로세스 제어: fg, bg, jobs, kill, …
❑ 사용자 (user)
▪ 자원의 사용 권한 제어
▪ 일반 사용자 vs. 관리자 (superuser)