[Operating System] Ostep virtualization - process API
2022. 10. 7. 21:46ㆍCS/OS
Ostep
운영체제 아주 쉬운 세 가지 이야기 : 네이버 도서 (naver.com)
프로세스 API
책에서는 Unix 시스템의 프로세스 생성에 관해 말을 한다.
더보기
Unix
1960년대 등장한 운영체제이다. 워크스테이션 / 서버용이었지만 데스크톱이나 임베디드용으로도 사용이 된다.
처음으로 C언어로 커널까지 작성된 운영체제이며, c언어를 통해 개발이 되어 다른 하드웨어로 이전이 쉬웠다.
또한 멀티태스킹 기술의 도입으로 여러사용자의 동시 작업이 가능하게 되었다.
# C언어는 유닉스를 프로그래밍 하기 위해 개발된 고급 프로그래밍 언어
이때 Unix는 프로세스 생성에 아래의 해당 시스템 콜들을 사용한다.
- fork()
- exec()
- wait()
- kill()
왜 이러한 API(Application Programming Interface)를 사용할까?
fork()
fork()
- unix에서 사용하는 프로세스가 자체 복사본을 생성하는 작업이다.
- 이때 생성된 프로세스를 위해 메모리가 할당
- 일반적으로 C 표준 라이브러리(libc) 래퍼로서 커널의 포크, 클론 또는 다른 시스템 호출에 구현에 사용된다.
- unix os에서 가장 주된 프로세스 생성 방법이다.
- 이때 생성된 자식 프로세스는 부모 프로세스의 힙, 정적 메모리, IPC, 열린 파일, etc를 복제
- fork()의 시스템 콜의 반환 값이 서로 다르다.
// unistd.h header file
pid_t fork(void); // 성공 시 : 부모 프로세스에서는 자식 프로세스의 PID값을 반환 받음
// 자식 프로세스에서는 0 값을 반환 받음
// 실패 시 : 음수 값(-1) 반환
#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 실패; 종료
fprintf(stderr, “fork failed\n ”);
exit(1);
} else if (rc == 0) { // 자식(새 프로세스)
printf(“hello, I am child (pid:%d)\n ”, (int) getpid());
} else { // 부모 프로세스는 이 경로를 따라 실행된다 (main)
printf(“hello, I am parent of %d (pid:%d)\n ”,
rc, (int) getpid());
}
return 0;
}
해당 코드는 책에서 존재하는 fork()를 호출하고 결괏값을 받아오는 코드이다.
rc값에 fork를 호출하고 값을 받아오면서 각 rc값에 맞게 코드를 진행한다.
- print(hello world) 및 해당 process identifier 를 출력
- rc에 fork를 통해 메모리 할당
- 이때 새로 생긴 메모리를 할당 받는 프로세스를 자식 프로세스, 생성하게 된 프로세스를 부모 프로세스
- 자식은 부모의 복제품이기에 똑같이 주소 공간 / 레지스트리 / pc값 소유
- 자식 / 부모의 fork() 시스템 콜의 반환 값이 틀리다.
- 부모는 그대로 실행 / 자식은 fork된 순간부터 실행
- 부모는 그대로 출력
- rc==0이 fork()를 통해 반환 되었으므로 자식 프로세스는 else if문 실행을한다.
- 자식은 else if 에 맞춰서 출력
wait()
wait()
- 부모 프로세스가 자식 프로세스의 종료를 대기해야 하는 경우도 존재
- wait() / waitpid() 시스템 콜 사용
#include <sys/wait.h>
pid_t wait(int *statloc);
성공 : 프로세스 ID 반환
오류 : -1
- 자식 프로세스 정상 종료
- wait() 반환값 : 프로세스 ID
- 자식 프로세스 비정상 종료
- wait() 반환값 : 프로세스 ID
- wait 함수 오류
- wait() 반환값 : -1
#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 실패 종료
fprintf(stderr, “fork failed\n ”);
exit(1);
} else if (rc == 0) { // 자식 프로세스
printf(“hello, I am child (pid:%d)\n ”, (int) getpid());
} else { // 부모 프로세스 실행
int wc = wait(NULL);
printf(“hello, I am parent of %d (wc:%d) (pid:%d)\n ”,
rc, wc, (int) getpid());
}
return 0;
}
위에서 한 fork()에 wait()이 추가가 된 경우이다.
위의 경우에는 아까 fork()에서 wait()이 추가된 부분을 주의 깊게 봐야 한다.
- wait()이 호출된 부분은 바로 부모 프로세스가 실행이 된 부분이다.
- 해당 코드에서 부모 프로세스가 먼저 실행이 되는 순간 wait()이 실행이 된다.
- 이 부분에 의해 부모 프로세스는 바로 출력문을 실행하지 못하고 대기
- 자식 프로세스는 실행이 된다.
- 자식 프로세스가 종료
- 부모 프로세스의 출력
exec()
exec()
- 자기 자신이 아닌 다른 프로그램 실행해야 할 때 사용
- return 문의 사용과 동일한 기능을 가지고 있다.
#include <stdlib.h>
void _Exit(int status);
#include <unistd.h>
void _exit(int status);
#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) { // fork 실행 실패 exit
fprintf(stderr, “fork failed\n ”);
exit(1);
} else if (rc == 0) { // 자식 프로세스
printf(“hello, I am child (pid:%d)\n ”, (int) getpid());
char *myargs[3];
myargs[0] = strdup(“wc ”); // 프로그램 : wc : 단어 세기
myargs[1] = strdup(“p3.c ”); // 인자 : 단어 셀 파일
myargs[2] = NULL; // 배열의 끝 표시
execvp(myargs[0], myargs); //“wc" 실행
printf(“this shouldn't print out ”);
} else { //부모 프로세스 실행
int wc = wait(NULL);
printf(“hello, I am parent of %d (wc:%d) (pid:%d)\n ”,
rc, wc, (int) getpid());
}
return 0;
}
- fork로 자식 프로세스 생성
- 부모 프로세스는 wait()으로 인해 대기 상태 및 fork는 0 반환
- 0으로 인해 자식 프로세스 실행
- 자식 프로세스는 argv 같은 인자를 활용 및 전달하여 다른 프로그램 실행
- 새로운 프로세스를 생성하진 않음
- 자식 프로세스 실행 완료 후 부모 프로세스 실행
'CS > OS' 카테고리의 다른 글
[OS] Operating System - Thread & Concurrnecy (1) | 2024.01.04 |
---|---|
[OS] Operating System 01 - Introduction 02 (0) | 2023.12.28 |
[OS] Operating System 01 - Introduction (1) | 2023.12.27 |
[Operate System] Thread (0) | 2022.11.18 |
[Operating System] Ostep virtualization - process (0) | 2022.09.25 |