[운영체제] 프로세스 상태와 계층구조

Local Gaji·2023년 6월 17일

운영체제

목록 보기
3/19

🎈 프로세스 상태

프로세스는 여러 상태를 거치면서 실행된다.

  1. 생성 : 프로세스를 생성 중인 상태, PCB를 막 할당받음
  2. 준비 : CPU 할당 차례를 기다리고 있는 상태
  3. 실행 : CPU를 할당받아 실행 중인 상태 (일정 시간 동안)
    • 타이머 인터럽트가 발생하면 다시 준비상태로 넘어감
    • 입출력 장치 작업을 기다려야 한다면 대기상태로 넘어감
  4. 대기 : 입출력 장치에 입출력을 요청하고 입출력이 완료될 때까지 기다리는 상태
  5. 종료 : 프로세스가 종료된 상태, PCB와 메모리를 정리함


프로세스가 swap 영역으로 갈때는 "보류" 과정이 추가되어 7개의 상태를 가진다.

  • 보류 준비 : 준비 상태에서 디스크로 쫓겨남 (실행 가능한 상태에서)
  • 보류 대기 : 대기 상태에서 디스크로 쫓겨남 (입출력 기다리던 중에)
    • 이 상태에서 프로세스의 입출력이 완료되어도 곧바로 메모리로 돌아오지 않고 보류 준비 상태로 바뀐다.

하지만 요즘 운영체제는 demand paging을 써서 프로세스 전체가 아니라 페이지 단위로 필요한 것만 메모리에 올리고 안 쓰는 페이지만 내보냄

🎈 프로세스 계층 구조

프로세스는 그냥 갑자기 튀어나오는게 아니라 부모 프로세스로부터 태어나야한다. 컴퓨터를 부팅하면 최초의 프로세스가 실행되는데, 이 조상님같은 프로세스가 자식 프로세스를 낳는다. 프로세스들의 가족관계도를 프로세스 계층 구조라고 한다.

컴퓨터를 켜서 로그인을 하고 문서 편집기 프로그램을 실행할 때
  1. 사용자가 컴퓨터를 켠 순간 최초 프로세스가 생성
  2. 최초 프로세스는 PC 로그인을 담당하는 자식 생성
  3. 로그인 시 로그인 프로세스는 사용자 인터페이스 프로세스를 자식으로 생성
  4. 사용자 인터페이스 프로세스는 문서 편집기 프로그램을 자식으로 생성


그럼 프로세스를 어떻게 낳는걸까?


🎈 프로세스 생성 기법

  • fork : 부모 프로세스가 본인을 복제해서 자식 프로세스를 생성
    • 코드·데이터·힙·스택 등등 주소 공간 전부를 똑같이 복사함
    • 하지만 자식과 부모의 PID 값이나 물리 메모리 주소는 다름
  • exec : 자식 프로세스가 자신의 메모리 공간을 새 프로그램으로 교체
    • 운영체제가 현재 프로세스의 주소 공간을 통째로 폐기하고 그 자리에 새로 적재
    • 힙·스택이 초기화돼서 새 프로그램의 시작점부터 실행된다.

Copy-on-Write

  • 보통 fork 직후 exec을 한다. 그런데 용량이 큰 프로세스를 힘들게 복제하자마자 exec으로 초기화 하는 것은 비효율적이다.
  • Copy-on-Write 기법은 복사를 최대한 미룬다.
  • fork 시점엔 아무것도 복사하지 않는다. 부모와 자식이 같은 물리 페이지를 공유하고, 양쪽 페이지 테이블에서 그 페이지들을 전부 읽기 전용으로 표시한다.
  • 둘 중 하나가 그 페이지에 쓰기를 시도하면, 읽기 전용 페이지라서 CPU가 페이지 보호 폴트를 일으킨다. 이때 운영체제 핸들러가 깨어나서
    1. 새 물리 프레임을 하나 할당하고
    2. 원본 내용을 거기 복사한 뒤
    3. 쓰려던 프로세스의 페이지 테이블을 새 프레임으로 바꾸고 쓰기 권한을 준다.
  • 실제로 수정된 페이지만 복사되어서 효율적이다.
  • 물리 페이지마다 참조 카운트를 둬서, 공유 중(count>1)인데 쓰기가 들어오면 복사하고, 카운트가 1로 떨어지면 그땐 복사 없이 그냥 쓰기 허용해주는 식으로 관리함

좀비, 고아 프로세스

  • 자식이 exit 할때 프로세스가 한번에 사라지지 않고 PCB의 일부를 프로세스 테이블에 남긴다.
  • 커널이 부모한테 SIGCHLD 시그널을 보내면, 부모가 wait() / waitpid()를 호출해서 정상 종료인지, 몇번째로 종료되었는지 등에 대한 정보를 수거해가야 PCB가 사라진다
  • 좀비 : 자식이 종료되었는데 부모가 아직 wait()를 안 한 상태
    • 프로세스는 이미 죽어서 코드도 안 돌고 메모리도 없음, 종료 정보를 담은 PCB 껍데기만 테이블에 남아있음
    • 문제 : 부모가 영영 wait()를 안 하면 좀비가 계속 쌓여서 프로세스 테이블 슬롯/PID가 고갈되고 실제 장애 원인이 된다. (kill -9 으로 못 죽임, 부모가 wait()를 하게 만들거나, 부모가 종료되어야 한다)
  • 고아 : 부모가 자식보다 먼저 종료된 경우
    • 이때 운영체제가 이 자식을 init(PID 1)에게 입양시킨다. init은 주기적으로 wait()를 호출해서 입양한 자식이 죽으면 바로바로 수거해줌

0개의 댓글