운영체제 강의노트 정리 - 프로세스

프로세스

프로세스 개념

프로세스

실행 중인 프로그램

프로세스는 다음의 것들로 구성되어 있다.

  • 텍스트 섹션 : 프로그램 코드 위치
  • 현재 상태 : 프로그램 카운터를 포함한 현재 프로세스의 레지스터 값
  • 스택stack : 일시 데이터(파라미터, 복귀 주소, 지역 변수 등)를 저장하는 곳
  • 데이터 섹션 : 전역 변수를 저장하는 곳

프로그램 자체는 프로세스가 아니다.

여러 프로세스가 같은 프로그램과 관련되어 있다고 할지라도 서로 같은 것으로 간주하지 않는다.

프로세스의 상태

  • 생성중new : 프로세스가 생성 중

  • 실행중running : 프로세스가 실행 중

  • 대기중waiting : 프로세스가 어떠한 사건을 기다리는 중

  • 준비ready : 프로세스가 프로세서에 할당되기를 기다리는 중

  • 종료terminated : 프로세스 실행이 종료됨

  • 프로세스 생성이 완료되면 생성중 상태에서 준비 상태로 바뀐다.

  • 스케줄러 디스패치에 의해 준비 상태에서 실행중 상태로 바뀐다.

  • 인터럽트에 의해 실행중 상태에서 준비 상태로 바뀐다.

  • 입출력 또는 이벤트 처리를 기다리기 위해 실행중 상태에서 대기중 상태로 바뀐다.

  • 입출력 또는 이벤트 처리가 완료되면 대기중 상태에서 준비 상태로 바뀐다.

  • 프로세스 실행이 끝나면 실행중 상태에서 종료 상태로 바뀐다.

단일 프로세스 시스템에서 실행중 상태에 있을 수 있는 프로세스는 오직 하나지만, 많은 프로세스가 대기중 또는 준비 상태에 있을 수 있다.

대기중 프로세스는 현재 프로세서가 실행할 프로세스가 없더라도 실행될 수 없다.

유닉스에서의 프로세스 상태

  • 프로세스가 exit 시스템 호출을 수행하면 좀비 상태가 되어 프로세스의 종료 상태나 수행 결과를 얻을 수 있도록 한다.
  • 주기억 장치에 적재되어 있는 프로세스 수를 줄이기 위해 프로세스를 중지suspend할 수 있으며, 중지된 프로세스는 주기억 장치에서 일시적으로 제거되어 디스크에 보관되고, 재개될 때까지 스케줄링 대상에서 제외된다.

프로세스 제어 블록

PCB, Process Control Block

다음의 것들이 PCB에 의해 관리된다.

  • 프로세스 상태
  • 프로그램 카운터 : 다음에 실행할 명령어 주소
  • CPU 레지스터 : 실행중 상태에서 대기중 또는 준비 상태가 될 때 현재 레지스터의 값을 보관
  • CPU 스케줄링 정보
  • 주기억 장치 관리 정보 : 기준 레지스터, 한계 레지스터와 같은 주기억 장치 관리에 필요한 정보
  • 회계 정보 : CPU 사용 시간과 같은 통계 정보
  • 입출력 상태 정보 : 프로세스에 할당된 입출력 장치, 프로세스가 연 파일 목록 등

스레드

프로세스 모델에서 프로세스는 단일 실행 흐름을 가지며, 이를 스레드thread라고 말한다.

최근에는 하나의 프로세스가 여러 개의 실행 흐름을 가질 수 있게 되었으며, 말하자면 여러 개의 스레드를 가질 수 있게 되어 한번에 여러 개의 작업을 수행할 수 있다.

프로세스 스케줄링

다중 프로그래밍의 목적은 항상 어떠한 프로세스를 실행하는 것이며, 이를 통해 CPU 사용 효율을 최대화할 수 있다.

시분할 시스템의 목적은 프로세스를 빈번하게 바꾸어 가며 실행하여 사용자가 프로그램과 상호 작용할 수 있도록 하는 것이다.

스케줄링 큐

프로세스의 스케줄링을 위해 운영체제는 여러 종류의 큐를 관리한다.

큐는 일반적으로 연결 리스트로 구현되어 있다. 큐의 헤더는 첫 번째와 마지막 PCB를 가리키는 포인터를 가지고 있고, 각 PCB는 다음 PCB를 가리키는 포인터를 가지고 있다.

큐의 종류는 다음과 같다.

  • 작업 큐job queue : 프로세스가 시스템에 처음 들어와서 대기하는 큐
  • 준비 큐ready queue : 주기억 장치에 적재되어 실행을 기다리는 프로세스를 관리하는 큐
  • 장치 큐device queue : 장치를 사용하기 위해 기다리는 큐. 각 장치는 자신만의 장치 큐를 가지고 있다.
  • 대기 큐waiting queue : 특정한 사건마다 그 사건을 기다리는 프로세스를 관리하는 큐

프로세스가 실행중 상태일 때 발생할 수 있는 사건은 다음과 같다.

  • 입출력을 요청하면 프로세스는 해당 장치 큐로 옮겨진다.
  • 새로운 프로세스를 생성하여 그 프로세스의 종료를 기다리는 경우 대기 큐로 옮겨진다. 부모 및 자식 프로세스가 병행 수행이 가능한 경우 준비 큐로 옮겨진다.
  • 인터럽트가 발생하면 현재 수행 중인 프로세스를 중단하고 인터럽트를 처리해야 한다. 인터럽트 처리가 완료되면 일반적으로 현재 프로세스를 준비 큐로 옮긴다.

모드 스위치는 사용자 모드에서 커널 모드로 변경될 때 발생하며, 완전한 문맥 전환이 필요하지 않고 시스템 스택을 사용한다. (시스템 콜)

프로세스 스위치는 현재 실행 중인 프로세스를 중단하고 새로운 프로세스를 실행할 때 발생하며, 완전한 문맥 전환이 필요하다.

스케줄러

각 큐마다 다음 차례의 프로세스를 결정하여 주는 스케줄러scheduler를 가지고 있다.

스케줄러의 종류는 다음과 같다.

  • 입출력 중심 프로세스I/O-bound process
  • 계산 중심 프로세스CPU-bound process

장기 스케줄러long-term scheduler는 작업 스케줄러job scheduler라고도 불리며, 준비 큐에 수용하지 못하는 작업을 디스크에 유지되는 작업 풀에 유지하여, 작업 풀에서 준비 큐로 옮겨질 다음 작업을 결정한다.

이 스케줄러는 다중 프로그래밍의 정도를 결정하고, 입출력 중심 프로세스와 계산 중심 프로세스를 적절한 비율로 선택해야 한다.

유닉스는 장기 스케줄러를 사용하지 않는다.

단기 스케줄러short-term scheduler는 CPU 스케줄러라고도 불리며, 준비 큐에서 다음에 CPU에 할당하여 실행할 프로세스를 결정한다.

중기 스케줄러medium-term scheduler는 시분할 시스템에서 프로세스를 메모리에서 디스크로 옮겨 다중 프로그래밍의 정도를 조절하는 것에 사용된다.

단기 스케줄러는 장기 스케줄러와 비교하여 상대적으로 빈번하게 실행된다.

문맥 전환

문맥 전환context switch은 실행 중인 프로세스의 상태를 보관하고 새로운 프로세스의 상태를 CPU에 적재하는 과정을 말한다.

프로세스의 컨텍스트는 PCB에 저장된다.

문맥 교환에 소요되는 시간은 순수 오버헤드이다.

위의 오버헤드를 극복하기 위한 특수 명령어, 레지스터 집합, 스레드 사용 등의 방안이 있다.

프로세스에 대한 연산

생성

프로세스는 수행 도중에 여러 개의 새로운 프로세스를 생성할 수 있다.

이 때 프로세스를 생성하는 프로세스를 부모 프로세스parent process, 생성된 프로세스를 자식 프로세스child process라고 한다.

자식 프로세스는 그것이 필요로 하는 자원을 운영체제로부터 직접 받거나, 부모 프로세스의 자원에 한정되어 받을 수 있다.

자식 프로세스가 얻을 수 있는 자원을 한정하면 어떠한 프로세스가 수많은 자식 프로세스를 생성하여 시스템을 마비시키는 것을 방지할 수 있다.

부모와 자식 프로세스는 병행으로 실행되거나, 자식 프로세스가 완료될 때까지 부모 프로세스가 기다린다.

자식 프로세스에 부모 프로세스의 주소 공간의 복사본이 할당되며, 자신의 공간에 적재할 프로그램을 가지고 있다.

유닉스의 경우 다음과 같이 프로세스를 생성한다.

  • 각 프로세스는 프로세스 식별자PID, process identifier를 가지며 이에 의해 식별된다.
  • fork 시스템 호출을 통해 프로세스를 생성한다. 그 결과로 자식 프로세스는 부모 프로세스의 주소 공간의 복사본을 할당받는다.
  • 자식 프로세스는 보통 execlp와 같은 시스템 호출로 할당받은 기존 주소 공간에 새로운 프로그램을 덮어쓴 다음 그 프로그램을 수행한다.
  • 부모 프로세스는 할 일이 없으면 wait 시스템 호출을 통해 자식 프로세스의 종료를 기다릴 수 있다.

종료

프로세스는 자신의 마지막 문장을 수행 완료하면 종료되며, 이 때 exit 시스템 호출을 통해 운영체제에게 자신의 삭제를 요청한다.

이 때 자식은 부모에게 결과 데이터를 전달할 수 있고, 부모는 wait 시스템 호출을 통해 이 데이터를 전달받을 수 있다.

부모 프로세스는 abort 시스템 호출을 통해 자식 프로세스를 강제로 종료시킬 수 있다.

유닉스에서는 부모 프로세스가 종료되면 고아가 된 자식 프로세스는 init이라고 하는 시스템 프로세스를 새로운 부모로 설정한다.

프로세스 간 협력

독립 프로세스independent process : 다른 프로세스의 실행에 영향을 주지도, 받지도 않는 프로세스

협조 프로세스cooperating process : 다른 프로세스의 실행에 영향을 주는, 영향을 받는 프로세스

협조 프로세스는 정보 공유 / 계산 가속화(계산을 나누어 실행) / 모듈화(기능 분리) / 편리성(동시 실행) 측면에서 필요하다.

프로세스 간 협조가 이루어지기 위해서는 상호 통신하는 메커니즘과 동기화 메커니즘이 필요하다.

소비자 생산자 문제

생산자 프로세스는 소비자 프로세스가 필요로 하는 정보를 생산하며, 이를 공유하기 위해 버퍼를 공유해야 한다.

이 때 생산자의 생산 속도와 소비자의 소비 속도를 맞추어야 할 필요가 있다.

무한 버퍼의 경우 소비자는 기다려야 하는 경우가 있으나, 생산자는 기다려야 하는 경우가 없다.

유한 버퍼의 경우 소비자는 버퍼가 비워져 있으면 기다려야 하고, 생산자는 버퍼가 가득 차 있으면 기다려야 한다.

이러한 버퍼는 프로세스 간 통신IPC, InterProcess Communication 기능을 이용하여 만들 수 있으며, 프로그래머가 공유 메모리를 이용하여 직접 구현할 수도 있다.

프로세스 간 통신

IPC는 프로세스가 같은 주소 공간을 공유하지 않아도 프로세스 간에 통신하고 동기화해줄 수 있는 메커니즘을 제공한다.

메세지 전달 시스템

데이터의 공유 없이 프로세스 간에 통신을 할 수 있도록 해준다.

기본적으로 send(msg)receive(msg)의 두 가지 연산을 제공한다.

메세지 크기는 가변적일 수도 있고, 고정적일 수도 있다.

두 프로세스 간에 통신하기 위해서는 통신 링크가 필요하다.

명명

직접 통신

각 프로세스는 수신자 또는 송신자의 이름을 명백하게 제시해야 한다.

상대방의 이름만 알면 통신을 하고자 하는 프로세스 간에 자동으로 링크가 설정되며, 정확하게 두 개의 프로세스만 연관되며, 두 프로세스 간에는 오직 하나의 링크만 존재한다.

대칭 방식

  • send(P, msg) : 프로세스 P에게 msg를 전송한다.
  • receive(Q, msg) : 프로세스 Q로부터 msg를 수신한다.

비대칭 방식

  • send(P, msg) : 프로세스 P에게 msg를 전송한다.
  • receive(id, msg) : 임의의 프로세스로부터 msg를 수신한다. 송신한 프로세스의 이름이 id에 저장된다.

간접 통신

메세지는 메일 박스나 포트로 전달되며, 이를 통해 여러 개의 메일 박스를 이용하여 통신할 수 있다.

메일 박스를 서로 공유해야 통신이 이루어질 수 있다.

두 프로세스가 메일 박스를 공유하는 경우에만 프로세스 간에 링크가 설정되며, 링크는 여러 개의 프로세스와 연관될 수 있으며, 두 프로세스 간에는 여러 개의 링크가 존재할 수 있다.

  • send(A, msg) : 메일 박스 A로 msg를 전달한다.
  • receive(A, msg) 메일 박스 A로부터 msg를 수신한다.

여러 프로세스가 하나의 메일 박스로부터 메세지를 수신하려 할 때, 다음과 같은 제한을 둘 수 있다.

  • 메일 박스를 오직 두 프로세스 간에만 공유할 수 있도록 한다.
  • 한번에 한 프로세스만 receive를 실행할 수 있도록 한다.
  • 시스템이 두 프로세스 중 임의로 하나를 선택하여 하나만 실행할 수 있도록 한다.

메일 박스는 프로세스가 소유할 수도 있고, 운영체제가 소유할 수도 있다.

메일 박스를 프로세스가 소유하는 경우

  • 소유자와 그것의 사용자를 구분하며, 소유자는 그 메일 박스로부터 수신만 할 수 있고, 사용자는 그 메일 박스로 메세지를 전달만 할 수 있다.

메일 박스를 운영체제가 소유하는 경우

  • 메일 박스는 특정 프로세스에 연관되지 않는다.
  • 프로세스가 새로운 메일 박스를 생성하고, 메일 박스를 통해 메세지를 송수신하고, 메일 박스를 삭제하는 것을 가능하게 하는 메커니즘을 제공해야 한다.
  • 메일 박스를 생성한 프로세스가 기본적으로 소유자가 되며, 그 프로세스만이 이 메일 박스로부터 메세지를 수신할 수 있다.
  • 시스템 호출을 통해 소유권과 수신 권한을 다른 프로세스에게 줄 수 있다.

동기화

메세지 전달을 구현하는 방법

  • 봉쇄형blocking(동기식synchronous) : 송신 프로세스는 수신자가 메세지를 수신하거나 메일 박스가 받아들일 때까지 대기하며, 수신 프로세스는 수신할 메세지가 있을 때까지 대기한다.
  • 비봉쇄형nonblocking(비동기식asynchronous) : 송신 프로세스는 메세지를 수신하고 다른 작업을 수행하며, 수신 프로세스는 유효한 메세지를 수신하거나 널 메세지를 수신한다.

위의 방식은 여러 조합으로 사용될 수 있다.

버퍼링

교환되는 메세지는 임시 큐에 보관된다.

  • 무용량 : 링크는 대기하는 메세지를 가질 수 없으므로, 송신자는 반드시 수신자가 메세지를 수신할 때까지 기다려야 한다.
  • 유한 용량 : 송신자는 링크가 채워져 있는 경우 대기해야 한다.
  • 무한 용량 : 송신자는 대기하는 경우가 없다.

자동 버퍼링은 유한 용량 또는 무한 용량의 버퍼를 사용하는 것을 말한다.

클라이언트-서버 시스템에서의 통신

소켓

소켓socket은 통신의 끝을 정의하며, 네트워크를 통해 통신하는 두 프로세스는 각자 소켓을 만들고 그것을 이용하여 통신한다.

소켓은 IP 주소와 포트 번호에 의해 식별된다.

특정 서비스를 제공하는 서버는 80(HTTP)과 같은 잘 알려진 포트 번호로 클라이언트의 요청을 기다린다.

TCP, UDP 등의 소켓이 있다.

원격 프로시저 호출

원격 프로시저 호출RPC, Remote Procedure Call을 통해 원격에 있는 프로시저를 지역 프로시저를 호출하듯 호출할 수 있도록 해준다.

RPC는 소켓보다는 상위 레벨의 통신 메커니즘이다.

원격에서 프로시저를 호출할 수 있도록 하기 위해서는 먼저 그것들을 사용할 수 있도록 등록해 놓아야 한다.