호우동의 개발일지

Today :

article thumbnail

프로세스에 대한 연산

  • 대부분 시스템 내의 프로세스들은 병행 실행될 수 있으며, 동적으로 생성되고, 제거되어야 한다.
    운영체제는 프로세스 생성 및 종료를 위한 기법을 제공해야 한다.

 


프로세스 생성

  • 프로세스는 여러 개의 새로운 프로세스를 새로운 프로세스를 생성할 수 있다.
    • 부모 프로세스 : 프로세스를 생성하는 프로세스
    • 자식 프로세스 : 생성된 새로운 프로세스
      • 자식 프로세스는 또다시 다른 프로세스를 생성할 수 있다.
  • 부모와 자식 프로세스가 이어져 트리를 형성한다.

 


프로세스 식별자

  • 프로세스 식별자(pid) : 프로세스를 구분하는 데 사용하는 식별자

    • 해당 식별자는 보통 정수
    • UNIX, Linux 및 Windows와 같은 대부분의 현대 운영체제들이 사용
    • pid는 시스템의 각 프로세스에 고유한 값을 가지도록 할당
    • 이 식별자를 통해 커널이 유지하고 있는 프로세스 속성 탐색을 위한 색인으로 사용

  • pid = 1 (systemd 프로세스)

    • 모든 사용자 프로세스의 루트 부모 프로세스 역할을 수행
    • 시스템이 부트 될 때 생성되는 첫 번째 사용자 프로세스
    • 시스템이 부팅되면 다양한 사용자 프로세스를 생성
      • 웹, 프린트 서버, ssh 등을 생성
      • UNIX 시스템은 init 프로세스를 모든 자식 프로세스의 루트로 식별
        • 최근 배포판에서는 systemd로 대체

 


부모와 자식 프로세스 간 자원 전달

  • 자식 프로세스를 생성할 때, 작업을 하기 위한 자원이 필요
    • 자원 : CPU 시간, 메모리, 파일, 입출력 장치 등
  • 자식 프로세스가 자원을 얻는 방식

    1. 운영체제로부터 직접 얻는 방식
    2. 부모 프로세스가 가진 자원의 일부만을 사용하도록 제한
      → 자식 프로세스를 많이 만듦으로써 생기는 시스템 과부하를 방지
       
      • 메모리나 파일과 같은 몇몇 자원들을 자식 프로세스와 공유
      • 부모 프로세스의 자원을 분할하여 자식에게 나눠줌

  • 부모 프로세스는 자식 프로세스에게 초기화 데이터를 전달할 수 있음

 


프로세스 실행

  • 2가지 방식 존재

    1. 부모와 자식이 병행하게 실행을 계속함
    2. 부모는 자식이 실행을 종료할 때까지 기다림

  • 자식 프로세스는 주소 공간 측면에서 볼 때 2가지 상태가 있을 수 있음

    1. 자식 프로세스는 부모와 똑같은 프로그램과 데이터를 가짐(복사본이라는 뜻)
    2. 자식 프로세스가 자신에게 적재될 새로운 프로그램을 가지고 있다.

  • UNIX 운영체제에서의 프로세스 생성 및 실행
    fork()를 이용한 프로세스 생성
    • fork() : 새로운 프로세스를 생성하는 시스템 콜
      • 새로운 프로세스는 원래 프로세스의 주소 공간의 복사본으로 구성
        • 해당 기법은 부모 프로세스가 쉽게 자식 프로세스와 통신할 수 있게 함

      • 부모와 자식 프로세스는 fork() 명령어 후, 실행을 계속함
        But, fork()의 반환값이 서로 다르다.

        • 자식 프로세스의 fork() 반환값 → 0
        • 부모 프로세스의 fork() 반환값 → 양수

    • exec() : 이진 파일을 메모리에 적재(load)하고 그 프로그램을 실행하는 시스템콜

      • fork() 시스템 콜 다음에 둘 중 한 프로세스가 해당 시스템콜을 사용한다.
      • exec()을 사용한 프로세스는 자신의 메모리 공간을 새로운 프로그램으로 교체한다.
      • 프로세스의 주소 공간을 새 프로그램으로 덮어쓰기 때문에
        오류가 발생하지 않는 한 제어를 반환하지 않는다.

    • fork()exec()

      • 해당 작업을 통해 부모는 더 많은 자식을 생성할 수 있다.

      • 자식이 실행되는 동안, 부모가 할 일이 없으면, wait() 시스템 콜 호출
        ← 준비(ready) 큐에서 자신을 제거하기 위해

 


프로세스 종료

  • 프로세스를 종료하면 사용하던 자원은 운영체제를 되찾아간다.
  • wait() : 자식 프로세스가 종료할 때까지 기다리는 시스템 콜
    • 부모가 자식의 종료 상태를 얻어낼 수 있도록 하나의 인자를 전달받음
    • 부모가 어느 자식이 종료되었는지 구별할 수 있도록 종료된 자식의 프로세스 식별자를 반환

  • 자발적 종료

    • exit() : 운영체제에게 자신의 삭제를 요청하고 종료하는 시스템콜
      • 해당 시점에서, 프로세스는 자신의 부모 프로세스에게 상태 값을 반환할 수 있다.
        • wait() 시스템 콜을 통해 가능하다.
        • 상태값 → 정수값
      • 프로세스의 모든 자원이 할당 해제되고 운영체제로 반납된다.
        • 물리 메모리, 가상 메모리, 열린 파일, 입출력 버퍼 등을 포함한 자원
      • 종종 종료 상태를 나타내는 인자를 전달받음
  • 비자발적 종료

    1. 부모 프로세스의 시스템콜 호출로 인해 종료되는 것
      • 부모가 자식을 종료시키기 위해서는 자식의 pid를 알아야 한다.
        • 자식 프로세스를 만들 때, 새 프로세스의 pid가 부모에게 전달됨

    2. 오작동으로 인해 다른 사용자의 프로세스를 임의로 중단(kill) 시키는 것
    • 부모가 자식을 종료할 수 있는 경우
      • 자식이 자신에게 할당된 자원을 초과 사용할 때
      • 자식에게 할당된 작업이 더 이상 없을 때(필요 없을 때)
      • 부모가 exit()하는데, 운영체제가 자식이 실행을 계속하는 것을 허용하지 않는 경우

  • 몇몇 시스템에서는 부모 프로세스가 종료한 이후에 자식 프로세스는 존재할 수 없다.
    • 연쇄식 종료 : 정상적, 비정상적이든, 모든 자식 프로세스들은 종료되어야 한다.
      • 해당 작업은 운영체제가 실행

 


좀비 프로세스와 고아 프로세스

  • 좀비 프로세스 : 종료되었지만 부모 프로세스가 아직 wait()를 호출하지 않은 프로세스
    • 종료하게 되면 모든 프로세스는 아주 짧은 순간 동안만 좀비 프로세스가 됨
    • wait()를 호출하면 좀비 프로세스의 프로세스 식별자와 프로세스 테이블 항목이 운영체제에 반환
  • 고아 프로세스 : 부모 프로세스가 자식 프로세스보다 먼저 종료될 때 발생
    • UNIX → 고아 프로세스의 새로운 부모 프로세스를 init 프로세스로 지정함으로써 이 문제를 해결
      • init 프로세스는 주기적으로 wait()를 호출하여 고아 프로세스의 종료 상태를 수집
        → 프로세스 식별자와 프로세스 테이블 항목을 반환받음