OS/OS-42study

5. 프로세스 관리

재윤 2023. 9. 13. 02:25
반응형

1. 프로세스의 개념

→ 프로세스(process)란 실행 중인 프로그램(program in execution)을 뜻함.

디스크에 실행 파일 형태로 존재한 프로그램 → 메모리에 올라가서 실행 시작 → 생명력을 갖는 프로세스가 됨. → 프로세스 CPU 획득 자신의 코드 수행, CPU를 반환하거나 입출력 작업 수행. → 자신의 임무를 다 수행하고 나면 종료 되고 사라짐.

잡(job) == 프로세스

프로세스 이해하기 → 프로세스의 문맥(context)에 대해 알 필요가 있음.

프로세스 문맥이란?

→ 프로세스가 현재 어떤 상태에서 수행되고 있는지 정확히 규명하기 위해 필요한 정보를 의미

프로세스 시작, 종료할 때까지 CPU에서 명령을 한꺼번에 수행하면 좋겠지만 → 여러 프로세스가 함께 수행되는 시분할 시스템 환경에서는 타이머 인터럽트에 의해 짧은 시간 동안 CPU를 사용한 후 빼앗겼다가 추후에 다시 CPU를 획득하는 식으로 CPU 관리가 이루어짐.

 

CPU를 다시 획득 → 명령의 수행을 재개하는 시점 → 이전의 CPU 보유 시기에 어느 부분까지 명령을 수행했는지 직전 수행 시점의 정확한 상태를 재현할 필요 생김. → 이때 정확한 재현을 위해 필요한 정보가 바로 프로세스의 문맥

 

프로세스 문맥

→ 그 프로세스의 주소 공간(코드, 데이터, 스택 상태)를 비롯해 레지스터에 어떤 값을 가지고 있었는지와, 시스템 콜 등을 통해 커널에서 수행한 일의 상태, 그 프로세스에 관해 커널이 관리하고 있는 각종 정보를 포함하게 됨.

3가지로 분류

  1. 하드웨어 문맥
    1. CPU의 수행 상태를 나타내는 것으로 프로그램 카운터값과 각종 레지스터에 저장하고 있는 값.
  2. 프로세스의 주소 공간
    1. 프로세스는 코드, 데이터, 스택으로 구성되는 자기 자신만의 독자적인 주소 공간을 가지고 있다.
    2. 프로세스의 주소 공간은 그 프로세스의 문맥을 결정짓는 중요한 요소 중 하나임.
  3. 커널상의 문맥
    1. 프로그램이 수행되어 프로세스가 되면 운영체제는 프로세스를 관리하기 위한 자료구조를 유지.
    2. PCB와 커널스택(kernel stack)이에 해당하며 프로세스의 문맥을 구성하는 중요한 요소.

 

2. 프로세스의 상태

프로세스의 상태는 실행(running), 준비(ready), 봉쇄(blocked, wait, sleep)의 3가지로 구분됨.

 

실행 상태

실행 상태 → CPU를 보유하고 기계어 명령을 실행하고 있는 상태.

컴퓨터 시스템은 일반적으로 CPU는 하나임. → 컴퓨터 내에서 여러 프로세스가 동시에 수행된다고 해도 실제로 실행 상태에 있는 프로세스는 매 시점 하나임.

 

준비 상태

준비 상태 → 프로세스가 CPU만 보유하면 당장 명령을 실행할 수 있지만 CPU를 할당 받지 못한 상태.

 

봉쇄 상태

봉쇄 상태 → CPU를 할당받더라도 당장 명령을 실행할 수 없는 프로세스의 상태를 말함.

ex) 프로세스가 요청한 입출력 작업이 진행 중 일 때.

3가지로 구분하는 이유가 뭐노?

→ 컴퓨터 자원을 효율적으로 관리하기 위해서임.

→ 프로세스가 생성 중이거나 종료 중인 일시적 상태를 시작(new) 상태, 완료(terminated) 상태라고 부르기도 함.

 

시작 상태

→ 프로세스가 시작되어 그 프로세스를 위한 각종 자료구조는 생성되었지만 아직 메모리 획득을 승인 받지 못한 상태.

 

완료 상태

→ 프로세스가 종료되었으나 운영체제가 그 프로세스와 관련된 자료구조를 완전히 정리하지 못한 상태를 말함.

하나의 프로세스는 앞서 말한 것처럼 어느 한 상태에 머물러 있게 됨.

그 상태는 시간이 흐름에 따라 변하게 됨.

ex)

실행 상태 → CPU의 제어권을 가지고 프로세스가 실행되는 중에 타이머 인터럽트 발생 → CPU의 제어권 운영체제로 이양됨. → 운영체제는 타이머 인터럽트 처리 루틴으로 가서 수행 중이던 프로세스의 문맥 저장 → 준비 상태에 있는 프로세스 중에서 새롭게 CPU의 제어권을 부여할 프로세스 선택 → 원래 수행 중이던 프로세스는 준비 상태로 변함, 새롭게 CPU를 할당 받은 프로세스 실행 상태가 됨.

 

문맥 교환

프로세스 변경

프로세스를 변경하기 위해 원래 수행 중이던 프로세스의 문맥을 저장하고 새로운 프로세스의 문맥을 세팅하는 과정을 문맥 교환이라함.

문맥 교환이 일어나는 경우

→ 타이머 인터럽트, 실행 상태에 있던 프로세스가 입출력 요청 등으로 봉쇄 상태로 바뀌는 경우

 

CPU 디스패치(dispatch)

준비 상태에 있는 프로세스들 중에서 CPU를 할당 받을 프로세스를 선택한 후 실제로 CPU의 제어권을 넘겨받는 과정을 CPU 디스패치(dispatch)라 함.

입출력을 요청한 프로세스의 상태 변화 예를 들어서 보자

프로세스 실행 상태 == CPU를 할당 받고 기계어 명령을 하나씩 수행

 

but 경우에 따라서 디스크에서 파일의 내용을 읽어와야 하는 명령이 포함될 수 있음.

→ 읽어온 결과가 있어야 후속 명령을 진행 가능 → 디스크에서 읽는 작업은 CPU 처리 속도에 비해 상대적으로 오랜 시간이 소요되는 작업 → 디스크 입출력이 진행되는 동안 프로세스가 CPU를 점유하고 있어도 후속 명령 처리 못함 → CPU가 비효율적으로 낭비 될 수 있다.

 

입출력이 완료될 때까지 CPU를 반환한 다음 디스크 입출력 서비스를 기다리며 봉쇄 상태로 바뀜 → CPU를 기다리는 준비 상태의 프로세스 들 중에서 CPU 스케줄러가 적절한 프로세스를 하나 선정해 CPU 할당. → 준비 상태의 프로세스는 CPU만 획득하면 곧바로 명령 수행 가능 → CPU를 할당 받은 프로세스는 실행 상태로 변경 → 자신의 코드 CPU에서 실행

 

디스크 입출력을 요청한 프로세스 상태 변화?

입출력을 요청한 프로세스는 디스크 입출력을 기다리는 큐에 줄 서 있음 → 자기 차례 되어 디스크 컨트롤러로부터 서비스 받음(원하는 데이터 로컬버퍼로 읽음) → 디스크 컨트롤러가 CPU에게 인터럽트 발생하여 입출력 완료 알림 → CPU 어떤 프로세스 실행하고 있다가 인터럽트 확인하여 그에 대응하는 루틴 수행 → 이 루틴 진행하는 동안 CPU에서 수행되던 프로세스의 상태 → 사용자 모드 실행 상태에서 커널모드로 실행 상태 바뀜

인터럽트 처리를 우리는 편의상 직전 프로세스의 문맥에서 실행 된 것으로 간주한다. == 프로세스가 실행되던 중에 인터럽트 발생 → 인터럽트 발생한 원인과 관계없이 인터럽트를 당한 프로세스가 사용자모드에서 실행되다가 커널모드로 진입한 것으로 간주

디스크 컨트롤러가 발생시킨 인터럽트는 입출력이 완료된 프로세스이 상태를 봉쇄 상태에서 준비 상태로 바꾼 후 → 장치의 로컬버퍼에 있는 내용을 메모리로 이동함.

 

인터럽트 처리 끝남 → 인터럽트 처리루틴 이전에 수행되던 프로세스에게 CPU를 다시 할당 → 프로세스의 직전 수행 시점 이후의 코드가 실행됨.

경우에 따라서 인터럽트 당한 프로세스에게 CPU를 다시 할당하지 않고, 입출력이 완료된 프로세스가 더 우선순위가 높은 프로세스인 경우 문맥 교환 → CPU제어권 이양시킴.

인터럽트 발생 전에 수행되던 프로세스가 아니라 방금 입출력을 끝낸 프로세스에게 CPU를 할당하는 경우도 있다는 것.

 

3. 프로세스 제어블록

프로세스 제어블록(Process Control Block:PCB)

→ 운영체제가 시스템내의 프로세들을 관리하기 위해 프로세스 마다 유지하는 정보들을 담는 커널 내의 자료구조를 뜻한다.

PCB의 요소

  1. 프로세스 상태(process state)
    1. CPU를 할당해도 되는지 여부 결정하기 위해 필요함.
  2. 프로그램 카운터(program counter)의 값
    1. 다음에 수행할 명령의 위치 가리킴.
  3. CPU 레지스터(CPU register)의 값
    1. CPU 연산을 위해 현 시점에 레지스터에 어떤 값을 저장하고 있는지 나타냄.
  4. CPU 스케줄링 정보(CPU schelding information)
    1. 각각 그 프로세스의 CPU 스케줄링과 메모리 할당을 위해 필요한 정보.
  5. 메모리 관리 정보(memory management information)
    1. 각각 그 프로세스의 CPU 스케줄링과 메모리 할당을 위해 필요한 정보.
  6. 자원 사용 정보(accounting information)
    1. 사용자에게 자원 사용 요금을 계산해 청구하는 등의 용도.
  7. 입출력 상태 정보(I/O status information)
    1. 프로세스가 오픈한 파일 정보 등 프로세스의 입출력 관련 상태 정보를 나타냄.

4. 문맥 교환

→ 하나의 사용자 프로세스로부터 다른 사용자 프로세스로 CPU의 제어권을 이양되는 과정.

 

사용자 프로세스 CPU 할당, 실행 → 타이머 인터럽트 발생 → CPU의 제어권 운영체제에게 넘어감. → 운영체제는 타이머 인터럽트 처리루틴으로 가서 직전까지 수행 중이던 프로세스의 문맥을 저장→ 새롭게 실행시킬 프로세스 CPU 이양. → 원래 수행 중이던 프로세스 준비 상태로 바뀜 → 새롭게 CPU를 할당받은 프로세스 실행 상태로 바뀜.

 

문맥 교환 중에 원래 CPU를 할당받은 프로세스는 프로그램 카운터값 등 프로세스의 문맥을 자신의 PCB에 저장 → 새롭게 CPU를 할당받을 프로세스는 예전에 저장했던 자신의 문맥을 PCB로부터 실제 하드웨어로 복원시키는 과정 거침.

문맥 교환은 타이머 인터럽트가 발생하는 경우 외에 실행 중이던 프로세스가 입출력 요청이나 다른 조건 충족하지 못해 CPU를 회수당하고 봉쇄 상태가 발생하는 경우도 있다.

 

프로세스 실행 상태 일 때 → 시스템 콜, 인터럽트 발생하면 CPU 제어권 → 운영체제 → 원래 실행 중이던 프로세스의 업무 잠시 멈춤 → 운영체제 커널의 코드 실행됨

이 경우에도 CPU의 실행 위치 등 프로세스의 문맥 중 일부를 PCB에 저장하지만 이러한 과정을 문맥 교환 x

이것은 하나의 프로세스가 실행모드만이 사용자 모드에서 커널모드로 바뀌는 것 뿐, CPU를 점유하는 프로세스가 다른 사용자 프로세스로 변경되는 과정 아님.

 

모드 변경에 비해 문맥교환에는 훨씬 많은 오버헤드(overhead)가 뒤따르게 됨.

타이머 인터럽트, 프로세스 입출력 요청, 시스템 콜 → 봉쇄 상태 → 문맥 교환 일어남

그 밖의 인터럽트, 시스템 콜 발생 시엔느 문맥교환 일어나지 않고 실행 모드만이 변경될 뿐. 즉 사용자 모드에서 커널 모드로 바뀌어 시스템 콜이나 인터럽트를 처리하지 않고, 다시 동일한 프로세스의 사용자 모드로 돌아와 이전에 수행하던 작업을 계속 수행할 뿐.

문맥교환 소요되는 시간

→ 시스템 입장에서 볼 때 일종의 오버헤드라고 할 수 있다.

 

문맥교환 중에 일어나는 작업이 실제 시스템에게 유용한 작업이 아님.

 

타이머에 CPU 할당 시간을 아주 작게 세팅해 프로세스 간 문맥교환이 빈번하게 발생하도록 하면 이에 드는 오버헤드가 상당히 커짐.

그 반대로 CPU 할당 시간을 너무 크게 설정하면 시분할 시스템의 의미가 퇴색됨. 적절한 CPU 할당 시간 정하는 것이 중요.

 

5. 프로세스를 스케줄링하기 위한 큐

운영체제 → 준비상태에 있는 프로세스들을 줄 세우기 위해 준비 큐를 둠.

 

준비 큐

제일 앞에 서 있는 프로세스에 제일 먼저 CPU를 할당. 프로세스를 줄 세 우는 방법은 CPU 스케줄링 방법에 따라 달라짐.

 

장치 큐

특정 자원을 기다리는 프로세스들을 줄 세우기 위해 자원별로 장치 큐를 둠.

ex) 예를 들어 설명

디스크 입출력 서비스 요청 프로세스 → 디스크 입출력 큐에 줄을 섬. → 디스크 컨트롤러는 디스크 입출력 큐에 줄 서 있는 순서대로 프로세스들의 입출력 작업 수행 → 프로세스별 입출력 작업이 완료 → 디스크 컨트롤러가 CPU에 인터럽트 발생 → 인터럽트 처리루틴에 의해 디스크 입출력 완료된 프로세스 입출력 큐 빠져나옴 → CPU를 기다리는 준비 큐에 줄 섬.

위에서 말한 것은 하드웨어 자원을 기다리는 프로세스들을 줄 세우기 위해 필요한 것임.

이번에는 소프트웨어 자원을 기다리는 경우를 보자

 

소프트웨어 자원

프로세스 —→ 공유 데이터 사용

  • 다른 프로세스가 같은 데이터 접근 → 데이터 일관성 훼손
  • 공유 데이터는 매 시점 하나의 프로세스만이 접근

접근 한다는 것이 CPU가 그 데이터를 사용하는 의미는 아님

프로세스 —> 공유 데이터 접근 중

  • 프로세스 준비 상태, 봉쇄 상태로 변경된 경우에 CPU를 할당받은 다른 프로세스가 동일한 데이터 접근 → 데이터 일관성 깨짐. 접근 허락 ㄴㄴ

쉽게 말해서

공유 데이터라는 일종의 소프트웨어 자원을 앞서 접근 중인 프로세스가 다 사용하고 반납할 때까지 다른 프로세스 CPU 할당 받더라도 접근하지말고 기다려야함.

해결 방법

공유 데이터를 기다리는 큐 사용!!!!

 

프로세스 상태 관리

프로세스 상태 관리 → 커널 → 커널의 주소 영역 중 데이터 영역 → 다양한 큐를 둠.

프로세스가 CPU를 기다리는지, 입출력을 기다리는지 등의 정보를 커널이 총제적으로 관리.

ex)

타이머 인터럽트

커널 → 자신의 데이터 영역 → 준비 큐 정보 참조 → 어느 프로세스에게 CPU 할당할지 결정. → 현재 실행 중인 프로세스 준비 큐 제일 뒤로 보냄.

 

작업 큐

운영체제는 준비 큐, 장치 큐, 작업 큐도 있음

작업 큐 → 시스템 내의 모든 프로세스를 관리하기 위한 큐, 프로세스의 상태와 무관하게 현재 시스템 내에 있는 모든 프로세스가 작업 큐에 속하게 됨. but 반드시 메모리를 가지는 것은 아님.

준비 큐 → 프로세스 준비 상태

장치 큐 → 봉쇄 상태

프로세스는 상태 변화에 따라 준비 큐와 장치 큐를 오가며 실행됨.

작업 큐가 가장 넓은 개념이고 준비 큐와 장치 큐에 있는 프로세스들은 모두 작업 큐에 속해 있다?

질문 → 작업 큐안에 준비 큐, 장치 큐가 있다고 하는데 그건 아닌듯.

 

운영체제 큐의 모습

  • 장치마다 큐를 하나씩 가짐
  • 큐헤더는 큐의 가장 앞부분.
  • 각 프로세스의 PCB를 연결 리스트 형태로 관리하며 포인터 사용해 순서를 정함.
  • 프로세스 CPU를 할당 받고 코드 수행 → 입출력 요청 → 해당 장치 큐에 줄 섬.
  • 장치 큐에 속한 프로세스들 봉쇄 상태 → 장치의 서비스를 받음 → 장치 컨트롤러 인터럽트 발생 → 준비 상태 → 준비 큐 이동.

 

6. 스케줄러

→ 어떤 프로세스에게 자원을 할당할지를 결정하는 운영체제 커널의 코드를 지칭.

스케줄러

  1. 장기 스케줄러 == 작업 스케줄러
  2. 단기 스케줄러

 

장기 스케줄러

→ 어떤 프로세스를 준비 큐에 진입시키질지 결정하는 역할.

준비 큐 → CPU만 얻으면 당장 실행될 수 있는 프로세스 집합. CPU에서 실행되기 위해서는 프로세스가 메모리를 보유해야함.

장기 스케줄러 → 프로세스에게 메모리를 할당하는 문제에 관여를 함.

처음 포로세스 생성 → 시작 상태를 거쳐 준비 상태 → 장기 스케줄러 시작 상태의 프로세스들 중 어떠한 프로세스를 준비 큐에 삽입할 것인지 결정하는 역할.

 

단기 스케줄러

→CPU 스케줄러라고도 함. 준비 상태의 프로세스 중에서 어떤 프로세스를 다음번에 실행 상태로 만들 것인지를 결정하는 것

준비 큐 ← 여러 프로세스 들 중 어떠한 프로세스에게 CPU를 할당할 것인가를 단기 스케줄러가 결정.

시분할 시스템에서는 타이머 인터럽트 발생하면 단기 스케줄러 호출됨.


스케줄러는 종류에 따라 고유한 특성을 지님.

단기 스케줄러 → 밀리초 정도의 시간 단위로 매우 빈번하게 호출됨 → 수행 속도가 충분히 빨라야함.

장기 스케줄러 → 수십 초 내지 수 분 단위로 가끔 호출되기 때문에 상대적으로 속도가 느린 것을 허용.

장치 스케줄러

  • 메모리에 동싱에 올라가 있는 프로세스의 수를 조절하는 역할을 함. → 시작 상태의 프로세스에게 메모리 할당을 승인할지 여부를 장기 스케줄러가 결정하기 때문

but 현대의 시분할 시스템에서 사용되는 운영체제에는 일반적으로 장치 스케줄러를 잘 두지 않음

 

과거에 자원이 빈약할 때 주로 사용됨. 적은 양의 메모리를 많은 프로세스들에게 할당하면 프로세스당 메모리 보유량이 지나치게 적어져 시스템의 효율이 매우 떨어지기 때문에 장기 스케줄러가 이를 조절함.

 

현대에서는 프로세스가 시작 상태가 되면 장기 스케줄러 없이 곧바로 그 프로세스에 메모리를 할당해 준비 큐 넣음.

 

중기 스케줄러

현대의 시분할 시스템용 운영체제에서는 장기 스케줄러 대신 중기 스케줄러를 두는 경우가 많음.

중기 스케줄러

  • 너무 많은 프로세스에게 메모리를 할당해 시스템의 성능이 저하되는 경우 이를 해결하기 위해 → 메모리에 적재된 프로세스의 수를 동적을 조절하기 위해 추가된 스케줄러

너무 많은 프로세스가 메모리에 적재되어 프로세스당 보우하고 있는 메모리양 극도로 작아짐 → CPU 수행에 당장 필요한 프로세스의 주소 공간조차도 메모리에 올려놓기 어려운 상황 발생

중기 스케줄러는 메모리에 올라와 있는 프로세스 중 일부를 선정해 이들로 부터 메모리를 통째로 빼앗아 그 내용을 디스크 스왑 영역에 저장 == 스왑 아웃(swap out)

 

쉽게 말해보자

중기 스케줄러는 프로세스당 보유 메모리양이 지나치게 적어진 경우 이를 완화하기 위해 일부 프로세스를 메모리에서 디스크로 스왑 아웃시키는 역할

 

중기 스케줄러 스왑 아웃

일부 프로세스를 메모리에서 디스크로 스왑 아웃시켜야 하는 경우 그 0순위인 프로세스 봉쇄 상태에 있는 프로세스.

봉쇄 상태인 프로세스를 모두 스왑 아웃 시켜도 메모리 공간 부족 → 타이머 인터럽트 발생해 준비 큐로 이동하는 프로세스를 추가적으로 스왑 아웃시킴.

중기 스케줄러는 장기 스케줄러와 마찬가지로 메모리에 올라와 있는 프로세스의 수를 조절하는 역할 수행

 

중기 스케줄러로 인해 프로세스 상태 추가

프로세스 상태의 실행, 준비, 봉쇄 외에 하나가 더 추가됨. 외부적인 이유로 프로세스의 수행이 정지된 상태를 나타내는 중지(suspended, stopped) 상태가 추가됨.

 

중지 상태 → 프로세는 외부에세 재개시키지 않는 이상 다시 활성화할 수 없어서 메모리 자원이 당장 필요하지 않음. 중지 상태의 프로세스는 메모리를 통째로 빼앗기고 디스크로 스왑 아웃된다.

디스크로 스왑 아웃된 프로세스의 상태가 대표적인 중지 상태

중지 상태

  1. 중지준비 상태
    1. 준비 상태에 있던 프로세스가 중기 스케줄러에 의해 디스크로 스왑 아웃 되면 중지준비 상태가 됨.
  2. 중지봉쇄 상태
    1. 봉쇄 상태에 있던 프로세스가 중기 스케줄러에 의해 스왑아웃 되면 중지봉쇄 상태가 됨.

중지봉쇄 상태이던 프로세스가 봉쇄되었던 조건을 만족하게 되면 이 프로세스의 상태는 중지준비 상태로 바뀜.

 

중지 상태에 있는 프로세스들은 중지준비 상태이든 중지봉쇄 상태이든 관계없이 메모리를 조금도 보유하지 않고 디스크에 통째로 스왑 아웃된 상태로 존재함.

 

7. 프로세스의 생성

운영영체제가 프로세스 전부 생성 x. 시스템이 부팅된 후 최초의 프로세스는 운영체제가 직접 생성하지만 그다음부터는 이미 존재하는 프로세스가 다른 프로세스를 복제 생성하게 됨.

생성한 프로세스 == 부모 프로세스

생성된 프로세스 == 자식 프로세스

부모 프로세스 → 자식 프로세스 생성 == 족보와 같은 계층 형성

프로세스의 세계 == 자식이 먼저 죽고, 자식을 생성했던 부모 프로세스가 처리를 함.

후손들을 여러 단계에 걸쳐 많이 생성한 프로세스가 종료될 경우 → 그 프로세스가 생성했던 모든 후손 프로세스들을 연쇄적으로 종료 시켜야 본인이 종료됨.

 

프로세스의 자원

→ 생성된 프로세스가 작업을 수행하기 위해서는 자원 필요.

자원을 획득하는 방법 → 운영체제 및 자원의 종류에 따라 상이.

  • 운영체제로부터 직접 자원을 할당받을 수 있음.
  • 부모 프로세스와 자원을 공유해서 사용.

 

프로세스 모델

  1. 부모와 자식이 공존하며 수행되는 모델.
    1. 자식과 부모가 같이 CPU를 획득하기 위해 경쟁하는 관계.
  2. 자식이 종료될 때 부모가 기다리는 모델.

자식이 종료될 때 부모가 기다리는 모델

  • 자식 프로세스가 종료될 때까지 부모 프로세스 아무 일도 하지 않고 봉쇄 상태에 머물르게 됨.
  • 자식 프로세스 종료되면 부모 프로세스 준비 상태가 되어 다시 CPU를 얻을 권한이 생김.

ex 유닉스 명렁어 입력창 → command 입력 → 커맨드의 수행 종료될 때까지 프로픔트 다시 띄우지 않음 → 명렁어 입력창을 띄운 부모 프로세스가 커맨드를 수행하고 자식 프로세스의 종료를 기다리며 봉쇄 상태에 머무르게 됨.

프로세스 생성 → 자신만의 독자적인 주소 공간을 갖게 됨.

  • 부모 프로세스 → 자식 프로세스 생성
    • 자식 프로세스는 부모 프로세스와 별도의 주소 공간 가짐.
    • 처음 주소 공간을 생성할 때에는 부모 프로세스의 주소 공간 내용 그대로 복사하여 생성.
    • 자식 프로세스가 다른 프로그램 수행하기 위해서 생성된 주소 공간 위에 새로운 프로그램의 주소 공간을 덮어씌워 실행.

ex) 프로세스 생성 절차 유닉스 fork() 시스템 콜 → 새로운 프로세스 생성 가능 fork() 시스템 콜은 자식 프로세스를 생성할 때 부모 프로세스의 내용을 그대로 복제 생성. 프로세스 ID를 제외한 모든 정보(운영체제 커널 내의 정보와 주소 공간의 정보)를 그대로 복사하는 방법 사용 결론 부모 프로세스와 자식 프로세스는 비록 주소 공간을 따로 갖게 되지만 주소 공간 내에는 동일한 내용을 가짐. fork() → exec() 시스템 콜을 통해 새로운 프로그램으로 주소 공간을 덮어씌울 수 있음.

 

유닉스 시스템의 전형적인 프로세스 계층도

  • 원칙적으로 부모 프로세스가 종료되기 전에 그 아래에 존재하는 모든 자식 프로세스들이 먼저 종료되어야함.

종료는 2가지로 나뉜다.

  1. 프로세스가 마지막 명령을 수행한 후 운영체제에 게 이를 알려 이루어지는 자발적 종료.
    1. 프로세스는 명령을 모두 수행한 후, 프로그램이 마쳐지는 코드 부분 exit()라는 시스템 콜을 넣어주도록 되어있음.
    2. 프로세스는 시스템 콜을 통해 운영체제에게 자신이 종료됨을 알림.
    3. 종료 통보받은 운영체제는 이 프로세스로부터 자원을 회수하고 시스템 내에서 이 프로세스 정리
    4. exit()함수 명시적으로 호출하지 않아도 컴파일러가 자동으로 삽입
  2. 비자발적 종료로 부모 프로세스가 자식 프로세스의 수행을 강제로 종료시키는 것.
    1. abort()라는 함수를 통해 이루어지게 됨.
    강제종료가 발생하는 경우
    1. 자식 프로세스가 할당 자원의 한계치를 넘어서는 많은 양의 자원을 요구할 때
    2. 자식 프로세스에게 할당된 작업이 더 이상 필요하지 않을 때
    3. 부모 프로세스가 종료되는 경우 등
    부모 프로세스가 종료되는 경우 → 운영체제는 자식 프로세스가 더 이상 수행되지 못하게 하기 때문에 단계적인 종료 발생.로그아웃 하게 되면 → 로그인 창 아래에 생성된 모든 자식 프로세스들이 종료 이러한 프로세스 계속 실행시키고 싶다 → 로그아웃 후에도 존재하는 시스템 프로세스의 자식으로 이양시키는 절차 필요!!!
  3. 쉽게 말해서 종료되는 프로세스의 자식 프로세스를 계속 실행시키기 위해 종료되지 않을 다른 프로세스의 양자로 자식 프로세스를 보내어 기존 부모 프로세스가 종료된 후에도 다른 프로세스 아래에서 계속 수행될 수 있도록 하는 것
  4. ex 사용자 계정으로 서버 컴퓨터에 접속 수행 시킨 프로그램 로그아웃 후에도 계속 수행 시켜야 하는 경우

 

프로세스가 자식 프로세스를 우째 생성할까?

운영체제 자식 프로세스 생성을 위해 fork() 시스템 콜을 제공

프로세스 fork() 시스템 콜 → CPU 제어권 커널로 넘어감 → 커널은 fork() 호출한 프로세스를 복제해 자식 프로세스를 생성 → fork() 시스템 콜을 하게 되면 fork() 함수를 호출한 프로세스와 똑같은 프로세스 하나 생성.

fork()를 통해 생성된 프로세스는 부모 프로세스와 모든 문맥을 동일하게 가지고 있다.

→ 부모 프로세스의 주소 공간을 비롯해 프로그램 카운터 등 레지스터 상태, PCB 및 커널스택 등 모든 문맥을 그대로 복제해 자식 프로세스의 문맥을 형성하게 되는 것임.

 

주의할 점!

  1. 자식 프로세스는 부모 프로세스의 처음부터 수행을 시작하는 것이 아님 부모 프로세스가 현재 수행한 시점 (프로그램 카운터 지점)부터 수행하게 됨.
  2. 운영체제가 프로세스 관리를 위해 사용하는 프로세스 식별자는 부모 프로세스와 다른 식별자를 가짐.

fork() 절차 이해해보기

  • 부모 프로세스가 한 줄씩 코드 수행 → fork()만남 → 자신과 똑같은 프로세스를 하나 생성하게 됨.
  • 현재 그 라인까지 수행했다는 기억조차도 똑같은 자식 프로세스가 생성되는 것
    • 복제된 프로세스가 자기 자신을 ‘복제했다’라는 기억을 가지게됨. 또한 원본이라고 생각함.
    • 원본 프로세스 == fork() == 양수 → 복제된 프로세스 사실을 알 수 있는 단서.
    • 복제 프로세스 == fork() == 0
    • 이런식으로 원본, 복제 프로세스가 다른 작업을 하도록 프로그램을 작성할 수 있음.

but

fork() 시스템 콜 → 프로세스 생성 → 그 결과값에 따라 부모, 자식 프로세스 다른 작업 수행 가능하지만 조건문에 의한 분기 일뿐 → 두 프로세스 모두 동일한 코드의 내용을 가질 수 밖에 없음.

자식 프로세스에게 부모와는 다른 독자적인 프로그램을 수행시킬 수 있는 메커니즘 필요. → exec() 사용

 

exec()

→ 유닉스에서는 프로세스의 주소 공간에 새로운 프로그램을 덮어씌우는 exec() 시스템 콜 지원.

  • exec() 시스템 콜은 프로세스가 지금까지 수행했던 상태를 잊어버리고 그 주소 공간을 완전히 새로운 프로그램으로 덮어씌운 후 새로은 프로그램의 첫 부분부터 다시 실행을 시작하도록 하는 시스템 콜.

 

정리

새로운 프로그램 생성 → fork()를 통해 기존 프로세스와 동일한 프로세스 복제

exec()을 통해 새롭게 수행시키려는 프로세스를 자식 프로세스의 주소 공간에 덮어씌우면 되는 것.

fork(),exec()는 특권 명령에 해당.

wait() 시스템 콜 → 자식 프로세스가 종료되기를 기다리며 부모 프로세스가 봉쇄 상태에 머무르도록 사용함.

fork() 후 wait() → 커널은 자식 프로세스가 종료될 때까지 부모 프로세스를 봉쇄 상테에 머무르게 하고, 자식 프로세스가 종료되면 부모를 준비 상태로 변경시켜 작업을 재개할 수 있도록 함.

부모 프로세스와 자식 프로세스 간의 동기화가 가능해짐.

wait() 시스템 콜을 한 후 부모 프로세스는 일반적인 봉쇄 상태에서처럼 자원을 기다리며 줄 서 있는 것이 아니라 자식 프로세스가 종료되기를 기다리며 수면 상태에 머무름. 자식 프로세스가 종료되는 순간 준비 큐에 재진입해 다시 CPU를 얻을 권한 획득

 

8. 프로세스 간의 협력

프로세스는 각자 자신만의 독립적인 주소 공간을 가지고 수행됨.

프로세스가 다른 프로세스의 주소 공간을 참조하는 것은 허용되지 않는다!!

하나의 프로세스는 다른 프로세스의 수행에 영향을 미칠 수 없다. 다른 프로세스와 정보를 주고 받을 수 있는 방법이 없기 때문.

부모 프로세스 → 자식 프로세스 생성할 때

  • 자식 프로세스가 부모 프로세스의 주소 공간을 복제하긴 하지만 생성이 완료된 후부터는 각자 자신의 독자적인 주소 공간만을 참조해 코드를 수행하므로 독립적인 관계가 됨.

독립적인 프로세스로 인해 협력할 때 업무의 효울성 증가, 부분적인 처리 결과나 정보 공유, 처리 속도가 향상될 수도 있는 등 여러가지 측면에서 효과적일 수도 있다. → 운영체제는 프로세스 간의 협력 메커니즘을 제공해 하나의 프로세스가 다른 프로세스의 수행에 영향을 미칠 수 있게 함.

 

IPC(인터프로세스 커뮤니케이션)

프로세스 간의 협력 메커니즘을 위해 운영체제가 제공하는 대표적인 케머니즘은 IPC(Inter-Process Communication: 인터프로세스 커뮤니케이션)

  • IPC는 하나의 컴퓨터 안에서 실행 중인 서로 다른 프로세스 간에 발생하는 통신을 말함.
    • 이 통신에서는 의사소통 기능과 함께 동기화를 보장해주어야함.
    • 공유 데이터를 서로 다른 두 프로세스가 사용할 수 있다고 하면 데이터의 불일치 문제가 발생할 수 있기 때문. → 그 데이터 접근 못하게 해야함.

즉, IPC는 프로세스들 간의 통신과 동기화를 이루기 위한 메커니즘을 의미.

IPC는 대표적인 방법으로 메시지 전달, 공유메모리 방식이 있다.

→ 이 두 방식의 차이는 프로세스 사이에 공유 데이터를 사용하는가 아닌가 임.

 

메시지 전달 방식

→ 프로세스 간에 공유 데이터를 일체 사용하지 않고 메시지를 주고 받으면서 통신하는 방식.

두 프로세스의 주소 공간이 다르므로 메시지 전달을 직접 할 수 없음 → 커널이 함.

커널

→ 메시지 통신을 하는 시스템 send(message), receive(message) 두 가지 연산.

이 두 연산을 통해 프로세스는 전달할 메시지를 운영체제에게 시스템 콜 방식으로 요청해 전달할 수 있다.

운영체제

  • 메시지를 주고받는 연산을 특권명령으로 규정해 커널을 통해서만 가능하도록 하고 있음.
  • 통신하기를 원하는 두 프로세스는 커뮤니케이션 링크(communica-tion link)를 생성한후 send()와 receive()를 이용해 메시지를 주고 받게 됨.

 

커뮤니케이션 링크 구현 방법

  1. 물리적인 방법
  2. 논리적인 방법

메시지의 전송대상이 다른 프로세스인지 아니면 메일박스라는 일종의 저종관인지에 따라 다시 직접통신, 간접통신으로 나뉨. 이 두 가지 방식의 차이는 연산의 인터페이스에 대한 차이일 뿐 실제 메시지 전송이 이루어지는 내부 구현은 커널의 중재에 의해 사실상 동일한 방식으로 이루어짐.

직접 통신

→ 통신하려는 프로세스의 이름이 명시적으로 표시.

send(P, message)는 프로세스 P에게 메시지를 전송하는 것을 의미.

receive(Q, message)는 프로세스 Q로부터 메시지를 전달 받는 것을 말한다.

  • 링크는 자동적으로 생성되고, 하나의 링크는 정확히 한 쌍의 프로세스에게 할당됨.
  • 각 쌍의 프로레스에게는 오직 하나의 링크만이 존재하고, 링크는 단방향성일 수 있으나 대부분의 경우 양방향성임.

 

간접통신

→ 메시지를 메일박스(mail box) 또는 포트(port)로 부터 전달 받음.

각 메일 박스에는 고유 ID가 있으며 메일박스를 공유하는 프로세스들만 서로 통신 가능.

 

간접통신에서 사용되는 커뮤니케이션 링크는 프로세스 간에 메일 박스를 공유하는 경우에만 생성됨.

 

  • 하나의 링크가 여러 프로세스들에게 할당될 수 있음.
  • 각 프로세스의 쌍은 여러 링크를 공유할 수 있음.
  • 링크는 단방향성 또는 양방향성일 수 있음.
  • 새로운 메일박스를 생성하는 연산, 메일박스를 통한 메시지의 send()/receive() 연산, 메일박스를 삭제하는 연산등이 사용됨.
    • send(A, message) → A라는 메일박스에 메시지를 전송하는 것.
    • receive(A, message) → A라는 메일박스로부터 메시지를 전달받음.

의문 상황?

→ p1, p2, p3가 메일박스 A를 공유하는 경우 p1이 메시지를 보낸다면 p2, p3 중 어는 프로세스가 메시지를 받게 되는가?

: 2개의 프로세스에게만 링크를 할당하는 방법 즉, p2와 p3에게 각각 따로 링크를 생성하는 것. 또는 링크에 대한 receive() 연산을 매 시점 하나의 프로세스만 수행할 수 있도록 하는 방법.

 

공유메모리 방식

→ 프로세스들이 주소 공간의 일부를 공유.

운영체제에서 공유메모리를 사용하는 시스템 콜을 지원 → 서로 다른 프로세스들이 그들의 주소 공간 중 일부를 공유할 수 있도록 한다.

  • 공유메모리 영역은 각자의 주소 공간에 공통적으로 포함되는 영역이므로 여러 프로세스가 읽고 쓰는 것이 가능.
  • 실제 구현은 프로세스 A와 B가 독자적인 주소 공간을 가지고 있지만, 이 주소 공간이 물리적 메모리에 매핑될 때 공유메모리 주소 영역에 대해서는 동일한 물리적 메모리 주소로 매핑됨.
  • 프로세스간의 통신을 수월하게 만드는 인터페이스 제공 but 서로의 데이터 일관성 문제 유발 → 커널이 책임지지 않음.
반응형

'OS > OS-42study' 카테고리의 다른 글

6. CPU 스케줄링  (0) 2023.09.13
4. 프로그램의 구조와 실행  (0) 2023.09.13
3. 컴퓨터 시스템의 동작 원리  (1) 2023.05.09
2. 운영체제의 개요  (3) 2023.05.09