[운영체제/OS] 시스템 콜(System Call)에 대한 간단한 정리

kindof

·

2021. 9. 23. 13:44

1. 시스템 콜(System calls)

운영체제에 대한 첫 포스팅부터 계속 System Call에 대한 인터럽트를 이야기했는데요.

 

그래서 지금 대표적인 System Call에는 어떤 것들이 있는지 잠깐 짚어보려고 합니다.

 

1. fork()

fork()는 새로운 프로세스를 생성하고, 프로세스 생성 요청을 보낸 프로세스(Calling Process)를 복제하는 시스템 콜입니다.

 
여기서 복제되는 프로세스를 Child, fork()를 수행하는 프로세스를 Parent라고 하는데요. fork()를 수행하게 되면 기본적으로 pid를 제외한 모든 내용이 동일하게 Child 프로세스에 복사됩니다.


또한, fork() 명령어 수행 시 Parent는 Child의 pid값을 리턴하고, child는 0을 리턴합니다. 그래서 이 리턴값을 기준으로 Parent, Child 프로세스를 구분하고, 각 프로세스가 다른 동작을 수행할 수 있게 할 수 있죠.

fork()

 


2. exec()

exec()는 fork() 수행 시 복제한 내용을 새로운 프로세스 내용으로 갈아치우는 시스템 콜입니다.

 

다시 말해서, exec()는 fork()와 쌍으로 같이 다니는 명령어인데 fork() + exec()를 수행하게 되면 1)새로운 프로세스를 만들고 2) 그 프로세스에 새로운 내용물을 넣는겁니다.


다만, exec()를 수행한다고 해서 다른 pid를 갖는 프로세스가 되는 것은 아니고, 그 내용물만 바뀝니다.

 

exec()의 사용

참고로 exec() 계열의 시스템 콜 함수에 대해서 알아보면 아래와 같습니다.

int execl(const char _path, const char *argo0, ..., const char *argn, (char *)0);
- path에 지정한 경로명의 파일을 실행하며 arg0~argn을 인자로 전달한다. 
- arg0에는 실행 파일명을 저장하고, 마지막 인자에는 인자의 끝을 의미하는 NULL 포인터를 지정해야 한다. 

int execv(const char _path, char *const argv[]); 
- path에 지정한 경로명에 있는 파일을 실행하여 argv를 인자로 전달한다. 
- argv는 포인터 배열이다. 이 배열의 마지막에는 NULL문자열을 저장해야 한다. 

int execle(const char _path, const char *argo0, ..., const char *argn, (char *)0, *const envp[]);
- path에 지정한 경로명의 파일을 실행하여 arg0~argn과 envp를 인자로 전달한다. 
- arg0~argn을 포인터로 지정하므로, 마지막 값은 NULL 포인터로 지정해야 한다. 
- envp는 포인터 배열이기 때문에 마지막에 NULL 문자열을 저장해야 한다. 

int execve(const char _path, char *const argv[], char *const envp[]);
- path에 지정한 경로명의 파일을 실행하여 argv, envp를 인자로 전달한다. 
- argv와 envp는 포인터 배열이다. 이 배열의 마지막에는 NULL문자열을 저장해야 한다. 

int execlp(const char _file, const char *arg0,..., const char *argn, (char *)0);
- file에 지정한 파일을 실행하여 arg0~argn만 인자로 전달한다. 
파일은 이 함수를 호출한 프로세스와 검색 경로에서 찾는다. 
- arg0~argn은 포인터로 지정하고, execl 함수의 마지막 인자는 NULL 포인터로 지정한다. 

int execvp(const char _file, char *const argv[]);
- file에 지정한 파일을 실행하여 argv를 인자로 전달한다. argv는 포인터 배열이다. 
- 이 배열의 마지막에는 NULL 문자열을 저장해야 한다.

 

3. wait()

wait()는 Child 프로세스가 종료될 때까지 기다려주는 역할을 하고, 프로세스 간 Synchronization을 도와줍니다. wait()를 통해서 Block을 하거나, Child가 수행한 상태의 결과값을 바로 리턴해야하는 상황 등에서 필요합니다.

 

 

4. exit()

exit()은 프로세스를 종료하는 시스템 콜입니다.