카테고리 없음

3. Process API?

HWAN JJ 2022. 5. 16. 17:37

Summary

Process API 들에 대해서.

  • Process API는 System Call이다
  • fork(), exec(), wait()란?
  • fork()와 exec()를 분리한 이유는?
    • IO redirection
    • pipe

fork() 함수? 자식 프로세스를 생성하는 API

 

Child process는 Separate memory space를 할당 받는다. 부모 프로세스와 같은 메모리 요소들을 가지고 있다.

  • Child process has its own registers, and program counter (PC)
  • 자식 프로세스는 부모 프로세스의 메모리를 복사한 다른 메모리를 사용한다. (부모, 자식 사이의 공유 X)

fork() 함수는 부모 프로세스에 pid를 return하고 자식 프로세스에는 0을 return 한다.

  • 부모 프로세스와 자식 프로세스는 다른 pid를 가지게된다
  • rc == 0 , rc > 0을 통해서 부모, 자식을 구분하고 프로그래밍 가능하다


⇒ 문제는?

  • 자식, 부모의 실행 우선순위를 보장할 수 없음
  • 자식, 부모 process는 independent 하고, 사이에 dependency가 없음

위에 문제를 해결하기 위해 wait() 함수가 등장했다.

  • wait() 함수는 부모 프로세스에서 실행되고, 자식 프로세스가 종료(exit())해서 자식의 pid를 return할 때까지 부모 프로세스를 대기시킨다.
  • 이를 통해서, 부모, 자식 프로세스 사이의 우선순위와 의존성을 만들 수 있다.


그러면 exec() 는 무슨 함수인가?

  • fork() 함수의 경우, 부모의 코드를 그대로 복사, 그런데 난 child에서 다른 프로그램을 실행하고 싶어⇒ Code를 새로운 Code으로 덮어씌우고, stack, heap 초기화해주는 exec() 함수
    ⇒ OS needs to load a new binary image, new stack, new heap...
  • 2개의 parameter 필요
    • The name of binary file (실행하고자 하는 파일)
    • The array of arguments (실행을 위한 인자들)

만약 exec()를 자식 프로세스에서 실행하면, 자식 프로세스의 그 이후의 실행문들은 실행되지 않아야한다.

exec()함수는 return 하지 않는다. 새로운 프로그램을 실행할 뿐이다.




Question. 그러면 forkandexec처럼 둘을 묶은 함수를 만들면 안 될까?

  • 2가지 이유가 있다.
  1. To manipulate various settings before executing
  2. Make I/O redirection and pipe possible

I/O redirection : 프로세스의 결과를 전달하는 또 다른 방법

  • file descriptor을 이용해서 program의 결과를 다른 파일에 저장할 수 있게해준다.
    • cat w3.c > newfile.txt ⇒ 이 경우에는 w3.c의 내용이 newfile.txt에 저장된다.
  • 반대로 프로그램의 입력을 파일로 받는 것도 가능하다.
    • ./a.out < input.txt ⇒ input.txt가 a.out의 input으로 들어간다.
  • How?
    • close() 함수를 이용해 STDOUT_FILENO(1), STD_INFILENO(0)을 닫고
    • open() 을 이용해 다른 파일들을 여는 방식으로 가능하다.


File descriptor

  • 0 = STDIN, 1 = STDOUT, 2 = STEDERR ⇒ 기본으로 할당된 값들
  • 각 fd마다 offeset이 있어서 offset 부터 읽는다.
  • close(1) 을 하고 open하면 1부터 할당된다.
  • file, pipe, directory, device 다 표현가능
  • 어떤 파일에 대한 포인터라고 생각할 수 있다. 리눅스 OS의 경우 모든 file, pipe, directory, device 들을 파일로 간주해서 처리하기 때문에 굉장히 유용한 파일을 향한 포인터

System calls about fd

  1. open()
    • Allocate new file object, fd, and set the fd에 새로 할당된 file object 연결
    • fd를 할당할 때는 비어있는 값중 가장 작은 값부터 할당해서 연결해준다.
  2. close()
    • fd 할당 해제
    • 더이상 연결된 fd가 없으면 연결되어 있던 file object도 해제
  3. fork()
    • 자식 프로세스는 부모의 fd table도 복제한다.
    • offset 역시 복제한다.
  4. exec()
    • retains file descriptor table (fd 유지)


PIPE

  • 한 프로그램의 ouput을 다른 프로그램의 input으로 줄 수 있다.
  • "|" 을 사용
  • Ex) echo hello world | wc

dup(), pipe() 함수..

  • Ordinary pipe
    • 그냥 "|" 사용
    • Unidirectional byte stream
    • No structured communication
    • 프로세스가 사라지면 pipe도 사라진다.

  • Anonymous Pipe - int pipe(int fd[2])
    • 한계: 오직 하나의 pair의 프로세스 간의 communication을 지원
  • Named Pipe
    • mkfifo(), mknod로 생성
    • 어떤 경로에 대한 pipe를 지정가능하다

pipe vs I/O redirection

  • pipe는 자동으로 clean themselves up, I/O redirection은 임시 파일 사용시 따로 삭제 필요
  • pipe 는 임의의 긴 data pass 가능, file redirection은 충분한 크기의 파일 필요
  • pipe는 writer, reader 둘 다 parallel 하게 실행, io redirection은 순차적으로 실행