MADE FOR ALL

블로그 이미지

MSNU

프로세스 관리(Process Management)

시리즈/OS 2014. 6. 23. 10:40

제 2 부  프로세스 관리(Process Management)


4. 프로세스(Process)


▶ 현대의 컴퓨터 시스템: ‘다중 프로그래밍’ 또는 ‘시분할 시스템’

즉, 다수의 프로그램을 기억장치에 적재하고 중앙처리장치를 다중화하여 병행 수행

→ 프로세스 개념 필요


4.1 프로세스 개념(Process Concept)


▶ 프로세스의 예

- 일괄처리 시스템의 작업(job)

- 시분할 시스템의 사용자 프로그램 또는 태스크(task)

- 스풀링과 같은 운영체제 내부 프로그램

→ ‘작업(job)’이라는 말과 혼용


4.1.1 프로세스(The Process)


▶ 프로세스의 정의: 실행중인 프로그램

- 프로그램 그 자체는 프로세스가 아님

1) 프로그램: 디스크에 저장된 파일과 같은 수동적인 실체(passive entity)

2) 프로세스: 다음 실행할 명령어를 지정하는 프로그램 카운터(program counter)를 가진 능동적인 실체(active entity)

- 프로세스의 실행은 순차적인 방식(sequential fashion)으로 진행됨

- 프로세스는 프로그램 코드 이상의 의미를 가짐, 현재 프로그램 계수기 값이 나타내는 활동요소(activity)와 프로세서의 레지스터를 포함함

- 두 프로세스들이 동일한 프로그램에 관련되어 있어도, 서로 분리된 실행 순서를 가짐

- 프로세스를 실행하는 과정에서 일반적으로 많은 프로세스들을 생성함


4.1.2 프로세스 상태(Process State)


▶ 순차 프로세스의 상태: [그림 4.1] 프로세스 상태도

- 생성(new): 프로세스가 생성되고 있음

- 준비(ready): 프로세서(CPU)에게 할당되기를 기다림

- 실행(running): 명령어들이 실행되고 있음

- 대기(waiting): 입출력 완료나 신호 수신과 같은 사건이 일어나기를 기다림

- 종료(terminated): 프로세스의 실행이 종료됨

* 어느 한 순간에 프로세서 상에서 오직 하나의 프로세스만이 실행됨


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


▶ 각 프로세스는 운영체제에 의해 프로세스 제어 블록(태스크 제어 블록)으로 표현됨

[그림 4.2] 프로세스 제어 블록

① 프로세스 상태: 생성(new), 준비(ready), 수행(running), 대기(waiting), 정지(halted)

② 프로그램 카운터: 프로세스의 다음 수행할 명령어 주소

③ 중앙처리장치 레지스터들

- 누산기(accumulator)

- 색인 레지스터(index register)

- 스택 레지스터(stack register)

- 범용 레지스터(general register)

- 상태 코드(condition code)

→ 인터럽트 발생시 프로그램 계수기와 더불어 저장됨으로써 추후 재개될 수 있게 함

  [그림 4.3] 한 프로세스에서 다른 프로세스로의 CPU 교환

④ 중앙처리장치 스케줄링 정보 → “5장 참조”

- 프로세스의 우선 순위

- 스케줄링 큐를 위한 포인터: 각 PCB는 다음 프로세스의 PCB를 가리키는 포인터를 가짐

- 기타 스케줄링 매개변수

⑤ 기억장치 관리 정보 → “8장 참조”

- 기준 레지스터(base register)

- 한계 레지스터(bound register)

- 페이지 테이블 또는 세그먼트 테이블의 정보

⑥ 계정 정보(accounting information)

- 중앙처리장치 및 실제 사용 시간

- 시간 제한

- 계정 번호

- 작업 또는 프로세스 번호

⑦ 입출력 상태 정보(I/O status information)

- 이 프로세스에 할당된 입출력 장치의 목록

- 개방된 파일의 목록


4.2 프로세스 스케줄링(Process Scheduling)


4.2.1 스케줄링 큐(Scheduling Queues)


▶ 스케줄링 큐: [그림 4.4] 준비 큐와 다양한 입출력 장치 큐

1) 준비 큐(ready queue): 준비 상태에서 실행을 기다리는 프로세스의 대기 장소

- 연결 리스트 구조

- 큐의 헤더: 두 포인터로 구성

① head 포인터 - 첫 PCB를 가리킴

② tail 포인터 - 끝 PCB를 가리킴

2) 장치 큐(device queue): 입출력 장치를 기다리는 프로세스의 대기 장소

- 각 장치마다 자신의 장치 큐를 가짐


▶ 큐잉 도표(queueing diagram): 프로세스 스케줄링의 표현 방식

[그림 4.5] 프로세스 스케줄링을 표현하는 큐잉 도표

- 사각형: 큐(준비 큐, 장치 큐)

- 원: 큐를 서비스하는 자원

- 화살표: 시스템에서의 프로세스 흐름


4.2.2 스케줄러(scheduler)


▶ 스케줄러: 큐에서 대기하는 프로세스의 선택 - 세 가지 유형


▶ 장기 스케줄러(long-term scheduler): ‘작업 스케줄러(job scheduler)’

- 목적: 프로세스 저장소(디스크)에서 처리할 대상 프로세스를 결정하여 기억장치로 이동시킴

1) 다중 프로그래밍 차수(기억장치에 있는 프로세스 수)의 안정적 유지

→ 프로세스가 시스템을 떠날 때마다 호출하면, 평균 프로세스 생성률과 평균 프로세스 이탈률이 동일해짐

2) 시스템 성능을 위해 입출력 중심 작업과 중앙처리장치 중심 작업을 잘 혼합하는 것이 좋음

  ① 입출력 중심 프로세스: 연산보다 입출력 수행에 더 많은 시간을 소요하는 프로세스

  ② 중앙처리장치 중심 프로세스: 입출력보다 연산 수행에 더 많은 시간을 소요하는 프로세스

- 실행 빈도: 少 → 장기 스케줄러는 다소 느려도 무방함


▶ 단기 스케줄러(short-term scheduler): ‘중앙처리장치 스케줄러(CPU scheduler)’

  - 목적: 주기억장치에 준비된 작업들 중에서 실행할 작업을 선택하여 중앙처리장치를 할당

  - 실행 빈도: 多 → 단기 스케줄러는 매우 신속해야 함


▶ 중기 스케줄러(medium-term scheduler): ‘교체(swapping)’ - 8장 참조

[그림 4.6] 큐잉 도표에 중기 스케줄링의 추가

- 목적: 기억장치에서 중앙처리장치에 대해 경쟁이 심한 프로세스의 수를 줄여 다중 프로그래밍의 차수를 완화시킴. 그 밖에도,

1) 프로세스의 혼합 상태 개선

2) 기억장치의 공간 확보 등에 활용 가능함

ex) 시분할 시스템의 경우, 장기 스케줄러를 거의 사용하지 않고 중기 스케줄러를 많이 사용함

→ 새로운 프로세스는 즉시 단기 스케줄러에 넣으며, 중기 스케줄러에 의한 기다림을 참지 못하는 사용자는 자리를 뜨게 됨


4.2.3 문맥 교환(Context Switch)


▶ 문맥 교환: 중앙처리장치를 다른 프로세스로 교환하기 위해 이전 프로세스의 상태를 보관하고 새로운 프로세스의 보관 상태를 적재하는 것


▶ 문맥 교환 시간은 하드웨어 지원과 운영체제의 복잡도에 따라 다양함

→ 성능상의 병목현상을 초래할 수 있음: 스레드(thread) 구조에 의한 해결(4.5절 참조)


4.3 프로세스 연산(Operation on Processes)


▶ 프로세스들은 병행 수행될 수 있어야 하며, 동적으로 생성 또는 제거되어야 함

  → 운영체제에 의한 프로세스 생성 및 종료 기법 제공 필요


4.3.1 프로세스 생성(Process Creation)


▶ 부모 프로세스 → 자식 프로세스(부 프로세스)

         ‘생성’ 시스템 호출

  [그림 4.7] 전형적인 UNIX 시스템의 프로세스 트리


▶ 부 프로세스의 자원 확보

- 운영체제로부터 직접 얻음

- 부모 프로세스의 자원을 이용:

1) 자식에게 자원을 분배

2) 자식과 자원을 공유

→ 너무 많은 부 프로세스를 만듦으로써 발생되는 시스템 부하를 줄일 수 있음


▶ 프로세스의 생성 시, 부모 프로세스에서 자식 프로세스로 초기 자료가 전달됨

ex) 파일 F1의 상태를 단말기 화면에 출력하는 부 프로세스

- 부모 프로세스로부터 F1이라는 파일 이름과 출력장치의 이름을 입력받고,

- 운영체제나 혹은 부모 프로세스로부터 자원을 할당받아 자료 전달을 수행함


▶ 프로세스의 운영 방식

- 수행 측면:

1) 부모 프로세스가 계속해서 자식 프로세스들과 함께 실행하는 경우

2) 부모 프로세스가 일부 혹은 모든 자식 프로세스가 종료될 때까지 기다리는 경우

- 주소 공간 측면:

1) 자식 프로세스가 부모 프로세스와 중복되는 경우

2) 자식 프로세스로 프로그램을 적재하는 경우


▶ 예:

  1) UNIX 운영체제

- 프로세스마다 고유 정수로 된 프로세스 식별자를 가짐

- fork 시스템 호출에 의해 생성되는 부 프로세스는 부모의 주소 공간을 복사한 것으로 구성되며, 부모 프로세스와 함께 수행됨

- fork 직후의 두 프로세스 중 하나가 execve 시스템 호출을 하여 새로운 프로그램을 자신의 프로세스로 (execve 시스템 호출을 가진 프로그램을 파괴하면서) 적재하고 수행을 시작함

- 부모는 수행되면서 또 다른 자식을 생성할 수도 있고, 자식이 종료될 때까지 기다리기 위해 wait 시스템 호출을 행할 수도 있음

2) DEC사의 VMS 운영체제:

- 새로운 프로세스를 생성하고 특정 프로그램을 적재하여 수행함

3) MS사의 윈도우즈/NT 운영체제:

- 부모 프로세스의 주소 공간에 중복시키는 방법과 새로운 프로세스의 주소공간으로 적재되는 프로그램 이름을 명시하는 방법 모두 제공


4.3.2 프로세스 종료(Process Termination)


▶ 프로세스의 종료 1

- 프로세스는 마지막 문장을 실행하고 exit 시스템 호출로 운영체제에게 자신의 삭제를 요청함

- 이때, 프로세스는 wait 시스템 호출로 기다리고 있는 부모 프로세스에게 자료(출력)를 반환할 수 있음

- 운영체제는 프로세스의 모든 자원(물리적 기억장치, 가상기억장치, 개방 파일, 입출력 버퍼 등)을 회수함


▶ 프로세스의 종료 2

- 부모 프로세스는 abort 시스템 호출을 통해 자식 프로세스를 종단(kill)시킬 수 있음

  또한, 사용자에 의한 프로세스 종단도 가능함

- 부모 프로세스가 자식을 식별할 수 있도록, 생성된 프로세스는 신원을 부모에게 전달함

- 부모 프로세스가 자식을 종료시키는 경우

1) 자식이 할당된 자원을 초과하여 사용하는 경우

  → 부모가 자식의 상태를 조사하는 메커니즘이 필요

2) 자식에게 할당된 업무(task)가 더 이상 필요 없는 경우

3) 운영체제에 의해 부모가 종료되면 더 이상 자식이 수행되는 것이 허용되지 않는 경우

  → “cascading termination”: 대부분의 운영체제에서 채택


▶ 예: UNIX

- 프로세스는 exit 시스템 호출을 하고 종료함

- 부모 프로세스는 wait 시스템 호출을 하고 기다림

- 자식 프로세스는 종료할 때 부모 프로세스에게 자신의 식별자를 알림

- 부모 프로세스가 종료되면 운영체제는 모든 자식을 종료시킴


4.4 상호 협조 프로세스들(Cooperating Processes)


▶ 병행 프로세스들의 유형

- 상호 독립적인 프로세스들: 상호 영향을 주고받지 않는 경우

  → 데이터를 공유하지 않는 경우는 명백히 독립적임

- 상호 협조적인 프로세스들: 상호 영향을 주고받는 경우

  → 데이터를 공유하는 경우는 명백히 협조적임


▶ 프로세스 협조를 허용하는 이유

- 정보 공유(information sharing): 여러 사용자가 동일한 정보에 동시 접근하는 경우

- 연산 속도 증가(computation speedup): 특정 태스크를 부태스크로 나누어 병행처리를 하는 경우

  → 다수의 처리 요소(중앙처리장치, 입출력 채널 등)를 갖는 경우에 가능

- 모듈성(modularity): 시스템 기능을 구분된 프로세스들로 나누어 모듈화 하는 경우

- 편의성(convenience): 한 사용자가 여러 태스크를 동시에 처리하는 경우

* 상호 협조적인 병행 수행을 위해서는 프로세스간의 통신(4.6절)과 동기화(6장)를 위한 메커니즘이 필요함


▶ 상호 협조적인 프로세스의 예: 생산자-소비자 문제

- 생산자 프로세스: 정보를 생산

  소비자 프로세스: 정보를 소비

ex) 인쇄 프로그램 →(문자)→ 프린터 구동기

    컴파일러 →(어셈블리 코드)→ 어셈블러 →(목적 모듈)→ 적재기(loader)

- 생산자와 소비자 프로세스의 병행 수행을 위해 버퍼의 저장소(pool)가 필요하고 동기화 되어야 함

1) 무한 버퍼: 버퍼의 수에 제한이 없는 경우

2) 유한 버퍼: 버퍼의 수가 제한되는 경우

- 기억장치에 의한 유한 버퍼를 구현한 생산자-소비자 프로그램: p.110-111

1) 공유 변수

- buffer: 순환 배열(circular array)

- in: 다음의 빈 버퍼를 가리키는 포인터

- out: 첫 번째의 찬 버퍼를 가리키는 포인터

2) 생산자 프로세스와 소비자 프로세스

- buffer가 빈 상태: in = out인 경우

- buffer가 가득 찬 상태: in+1 = out인 상태(실제로는 n-1개만 찬 상태임)

- no_op: 아무 것도 하지 않는 명령어


[프로그램]

const n = 100;

type item = ...;

var buffer: array[0..n-1] of item;

    in, out: 0..n-1;

    nextp, nextc: item;

    in := 0;

    out := 0;

    parbegin

        producer: begin

                      repeat

                          ...

                          produce an item in nextp

                          ...

                          while in+1 mod n = out do no-op;

                          buffer[in] := nextp;

                          in := in + 1 mod n;

                      until false;

                  end;

        consumer: begin

                      repeat

                          while in = out do no-op;

                          nextc := buffer[out];

                          out := out + 1 mod n;

                          ...

                          consume the item in nextc

                          ...

                      until false;

                  end;

    parend


4.5 스레드(Threads)


▶ 태스크를 구성하는 프로세스들간에 자원이 동시에 공유되고 접근되는 것이 유용할 수 있음

  → 스레드 기능


4.5.1 스레드 구조


▶ 스레드: 경량 프로세스(lightweight process; LWP)

- 중앙처리장치 사용의 기본 단위

- 프로그램 계수기, 레지스터 집합, 스택 공간으로 구성

- 동료 스레드들과 코드 구간, 데이터 구간, 운영체제 자원(개방된 파일, 신호 등)을 공유

  → 즉, 태스크를 공유

- 일반적인 의미의 프로세스인 중량 프로세스(heavyweight process; HWP)는 하나의 스레드를 가진 태스크에 해당

- 스레드 문맥 교환은 여전히 레지스터 집합의 교환을 필요로 하지만 기억장치관리 관련 작업은 필요로 하지 않으므로 프로세스 문맥 교환보다 신속함

- 병렬처리 환경과 유사하게, 다중 스레딩 프로세스는 임계영역이나 잠금을 필요로 하는 병행 제어 문제가 발생함


▶ 다중 스레드 제어 ↔ 다중 프로세스 제어

- 다중 프로세스의 경우, 각 프로세스는 독립적으로 수행함

즉, 각 프로세스는 자신의 프로그램 계수기, 스택 레지스터, 주소 공간을 가짐

→ 프로세스들에 의해 수행되는 작업들이 서로 무관할 때 유용

→ 프로세스들이 동일 코드를 수행할 수 있지만, 별도의 기억공간과 파일 자원을 소유해야 함

- 하나의 다중 스레드된 프로세스가 연관된 다중 프로세스들 보다 적은 자원(기억공간, 개방 파일, CPU 스케줄링 등)을 사용함

→ 효율을 극대화할 수 있음


▶ 스레드와 프로세스의 유사점과 상이점

1) 프로세스와의 유사점

- 생성(create), 준비(ready), 블록(blocked), 수행(running), 종료(terminated) 중 한 상태를 유지함

- CPU를 공유하고 한 순간에 하나의 스레드가 수행됨

- 순차적으로 수행되고, 각자의 레지스터와 프로그램 계수기를 가짐

- 자식 스레드를 생성할 수 있고, 시스템 호출이 완료될 때까지 기다리기 위해 블록할 수 있음

2) 프로세스와의 상이점

- 서로 독립적이지 않음

- 상호간의 보호가 제공되지 않음

→ 실제로 태스크내의 스레드들은 상호 지원하도록 설계되기 때문에 상호간의 보호는 필요하지 않음

[그림 4.8] 태스크내의 다중 스레드


▶ 스레드는 병행 처리뿐만 아니라 블로킹 시스템 호출에 의한 순차 처리도 허용함


▶ 공유 자원들에 대한 다중 스레드의 제어 방법

1) 커널 지원 스레드(kernel-supported threads) 방식: ex) Mach, OS/2

- 프로세스에서와 같은 시스템 호출 집합을 제공

2) 사용자 수준 스레드(user-level threads) 방식: ex) Andrew

- 사용자 수준에서의 라이브러리 호출 집합을 제공

- 스레드 교환은 운영체제 호출을 필요로 하지 않기 때문에 매우 신속

- 한 사용자 수준 스레드의 시스템 호출로 전체 프로세스(태스크)의 대기를 초래

→ 커널은 스레드에 대한 정보 없이 프로세스만을 스케줄하기 때문

- 스레드 입장에서는 불공정한 스케줄링 발생

ex) 프로세스 a: 1개의 스레드로 구성, 프로세스 b: 100개의 스레드로 구성

    두 프로세스에 동일한 수의 타임 슬라이스를 할당받음

→ 프로세스 a의 스레드가 프로세스 b의 스레드에 비해 100배 빨리 수행됨

→ 단, 커널 지원 스레드의 경우에는, 스위칭에 보다 많은 시간이 소요되지만 프로세스 b가 프로세스 a에 비해 100배 더 많이 받음

3) 사용자 수준 스레드와 커널 지원 스레드의 혼합(hybrid) 방식: ex) Solaris 2 → 4.5.2절 참조

- 혼합 방식은 스레드가 중량 프로세스의 특성을 다소 가지면서도 보다 효율적으로 수행되기 때문에 많이 사용됨

ex) UNIX: 커널이 단일 작업인 경우 - 즉, 커널에서는 단 하나의 태스크만 수행됨

→ 자료 접근의 동기화 문제를 피할 수 있음

ex) Mach: 커널이 다중 스레드된 경우 - 즉, 커널이 동시에 여러 요청을 서비스함

→ 스레드들이 공유 자료 접근에 대해 동기화되어야 함 → 동기화: 6장 참조


4.5.2 예: Solaris 2


▶ 시스템 구성

[그림 4.9] Solaris 2의 스레드

1) 사용자 수준 스레드(user-level thread)

- 사용자 수준 스레드의 생성과 스케줄링은 라이브러리 형태로 지원받으며, 커널은 전혀 관여하지 않음

2) 중간 수준 스레드(intermediate-level thread): 커널 지원 LWP(kernel-supported LWP)

- 사용자 수준 스레드들과 커널 수준 스레드들 사이에 있는 경량 프로세스들

  → 커널과의 통신이 필요한 경우에 사용

- 각 태스크는 적어도 하나의 LWP를 가짐

- 스레드 라이브러리에 의해 조작됨

- 사용자 수준 스레드들은 해당 LWP상에서 다중화됨

  즉, 현재 수행중인 사용자 수준 스레드가 LWP에 연결되고, 나머지는 블록되거나 기다림

3) 커널 수준 스레드(kernel-level thread)

- 커널내에서의 모든 수행은 커널 수준 스레드에 의해 수행됨

- 각 LWP를 위한 커널 수준 스레드와 LWP와 관계없이 커널 자신을 위한 커널 수준 스레드(ex. 디스크 요청 서비스를 위한 스레드)로 구분됨

- 어떤 커널 수준 스레드들은 처리기들 상에서 다중화되는 반면, 어떤 커널 수준 스레드들은 특별한 처리기에만 할당됨


▶ 시스템 동작

- 하나의 태스크는 많은 사용자 수준 스레드로 구성되고, 이들은 커널의 개입 없이 커널 지원 LWP에서 스케줄되고 교환됨

- 각 LWP는 정확히 하나의 커널 수준 스레드에 연결되며, 하나의 태스크에 여러 LWP가 존재할 수 있는데, 이들은 커널과의 통신을 필요로 하는 경우에만 존재함

- 커널 스레드는 커널의 스케줄러에 의해 스케줄되고 하나 혹은 여러 CPU 상에서 수행됨

- 커널 스레드가 (통상 I/O 연산이 완료되기를 기다리면서) 블록되면, 대응하는 LWP도 블록되고, 연쇄적으로 그 LWP에 부착된 사용자 수준 스레드들도 블록됨. 이때, 태스크가 소유한 LWP가 하나인 경우에는 그 태스크 전체가 블록됨


▶ 각 스레드 유형의 자원 요구

1) 커널 수준 스레드: 소규모의 데이터 구조 및 스택

→ 커널 스레드의 교환은 기억장치 접근 정보의 수정을 필요로 하지 않으므로 상대적으로 신속함

2) LWP: 프로세스 제어 블록(레지스터 데이터, 계정 정보, 기억 장치 정보 등)

→ LWP의 교환은 매우 많은 양의 일을 필요로 하기 때문에 상대적으로 느림

3) 사용자 수준 스레드: 스택과 프로그램 계수기(커널 자원 불필요)

→ 커널이 사용자 수준 스레드의 스케줄링에 개입하지 않으므로, 사용자 수준 스레드의 교환이 신속함


4.6 프로세스간 통신(Interprocess Communication; IPC)


▶ 프로세스간 통신(IPC): 프로세스간의 통신과 동기화를 제공하는 기법

- 메시지 시스템(message system): 좋은 효과를 보임

- 공유 기억장치(shared memory): 공용 버퍼 저장소에 대한 구현을 응용 프로그램에서 담당

→ 두 기법은 배타적이지 않으며 단일 운영체제 내에서 동시에 사용 가능


4.6.1 기본 구조(Basic Structure)


▶ 프로세스간의 통신을 위한 두 가지 기본 연산

- send (message)

- receive (message)


▶ 통신 연결(communication link)의 구현

1) 물리적 구현: 공유 기억장치, 하드웨어 버스, 네트워크 등 → 15장 참조

2) 논리적 구현: “고려 사항”

- 연결(link)의 설정 방법

- 하나의 연결에 연관될 수 있는 프로세스의 최대 수

- 각 프로세스 쌍에 존재할 수 있는 연결의 최대 수

- 연결의 용량(capacity): 버퍼 공간의 존재 여부 및 그 공간의 크기

- 메시지의 크기: 연결의 가변 길이 혹은 고정 길이 메시지 수용 여부

- 연결의 단방향(unidirectional) 또는 양방향(bidirectional): 메시지 흐름의 단방향/양방향 여부


▶ 연결(link)과 send/receive 연산의 논리적 구현 방법

① 직접 통신(direct communication) ↔ 간접 통신(indirect communication)

② 대칭 통신(symmetric communication) ↔ 비대칭 통신(asymmetric communication)

③ 자동적 버퍼링(automatic buffering) ↔ 명시적 버퍼링(explicit buffering)

④ 복사에 의한 전송(send by copy) ↔ 참조에 의한 전송(send by reference)

⑤ 고정 길이 메시지(fixed-sized message) ↔ 가변 길이 메시지(variable-sized message)


4.6.2 명칭 부착(Naming)

“통신을 원하는 프로세스들이 서로 참조할 수 있는 방법”


4.6.2.1 직접 통신(Direct Communication)


▶ 직접 통신: 메시지를 송신하거나 수신하는 프로세스가 상대 프로세스의 이름을 명시하는 방식

- send(P, message): 프로세스 P에게 메시지를 전송

- receive(Q, message): 프로세스 Q로부터 메시지를 수신


▶ 직접 통신 연결의 특성

① 통신을 원하는 프로세스 쌍 사이에 연결이 자동 설정됨

  → 프로세스들은 서로 상대방의 신원을 알아야 함

② 연결은 두 프로세스 사이에만 지정됨

③ 통신 프로세스 쌍 사이에는 정확히 하나의 연결이 존재함

④ 연결은 단방향일 수 있지만, 일반적으로 양방향임


▶ (예) 생산자/소비자 문제의 해결 방안: p.120의 프로그램


▶ 주소지정(addressing) 방식

1) 대칭적(symmetric): 송신자와 수신자 모두 상대방을 명명

2) 비대칭적(asymmetric): 송신자만 수신자를 명명하고, 수신자는 송신자를 명명할 필요 없음

- send(P, message): 프로세스 P에게 메시지를 전송

- receive(id, message): 임의의 프로세스로부터 메시지를 수신

                     (id: 통신을 일으킨 프로세스의 이름으로 설정됨)


▶ 직접 통신의 단점: 프로세스 정의의 모듈성(modularity) 제한

  → 즉, 이름 변경시 다른 모든 프로세스의 정의(옛 이름 포함)를 조사해야 함




4.6.2.2 간접 통신(Indirect Communication)


▶ 간접 통신: 메일박스(mailbox)를 통한 통신 → “port”라고도 함

- 프로세스에 의해 메시지가 놓여지거나 제거되는 객체

- 각 메일박스는 고유한 id를 가짐

- 두 프로세스는 공유 메일박스를 가질 때만 통신할 수 있음

1) send(A, message): 메일박스 A로 메시지를 송신

2) receive(A, message): 메일박스 A로부터 메시지를 수신


▶ 간접 통신 연결의 특성

① 한 쌍의 프로세스가 공유 메일박스를 가질 경우에만 연결이 설정됨

② 하나의 연결이 둘보다 많은 프로세스들과 연관될 수 있음

③ 각 통신 프로세스 쌍 사이에 여러 연결(메일박스)이 있을 수 있음

④ 연결은 단방향일 수도 양방향일 수도 있음


▶ 프로세스 P1, P2, P3가 메일박스 A를 공유할 때,

- P1: A에 메시지 송신 → P2와 P3가 A로부터 메시지를 수신하려는 경우

                  “누가 수신?”

(해결책)

① 하나의 연결이 기껏해야 두 프로세스에만 연관되도록 함

② 기껏해야 한번에 한 프로세스만이 receive 연산을 실행하도록 허용함

③ 시스템이 임의로 선택하고, 송신자에게 수신자를 알림


▶ 메일박스의 소유권: “프로세스” ↔ “시스템(운영체제)”

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

- 소유자(메일박스로부터 메시지를 수신하는 프로세스)와 사용자(메일박스에 메시지를 송신하는 프로세스)를 구분할 수 있음

- 프로세스가 종료할 때 그 프로세스가 소유한 메일박스도 사라짐

- 소멸된 메일박스에 메시지를 송신하는 프로세스에게는 예외처리로 이 사실을 알려야 함

- 메일박스의 소유자와 사용자를 지정하는 방법:

  프로세스가 메일박스 형태의 변수를 선언하면 소유자가 되고,

  그 메일박스의 이름을 아는 모든 프로세스들이 사용자가 됨

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

- 메일박스가 독립적으로 존재

- 운영체제가 다음의 기능을 제공

① 새로운 메일박스의 생성

② 메일박스를 통한 메시지의 송수신

③ 메일박스의 소멸

- 새로운 메일박스를 생성하는 프로세스가 일차적으로 소유자가 되고 수신할 수 있음

- 소유권/수신권은 적절한 시스템 호출에 의해 다른 프로세스에 이전할 수 있음

→ 다중 수신자 발생 가능

- 프로세스들은 프로세스 생성기능을 통해서 메일박스를 공유할 수 있음

ex) 프로세스 P가 메일박스 A를 생성한 후, 다른 프로세스 Q를 생성하면, Q는 A를 공유함

- 메일박스가 어떠한 프로세스에 의해서도 접근되지 않는 경우

→ 쓰레기 수집(garbage collection)으로 해결


4.6.3 버퍼링(Buffering)


▶ 연결(link)의 용량: 임시로 저장할 수 있는 메시지의 최대 수 → ‘메시지 큐’

① 무용량(zero capacity): 큐의 길이가 0인 경우

- 송신자는 수신자가 메시지를 수신할 때까지 기다려야 함

  즉, 두 프로세스간에 메시지 전달을 위해 동기화가 필요 - “회합(rendezvous)”

→ “비버퍼링”

② 한계 용량(bounded capacity): 큐의 길이가 n>0인 경우

- 송신자는 큐가 만원이 아니면 메시지를 큐에 넣고 계속 수행하고, 그렇지 않으면 기다려야 함

→ “자동 버퍼링”

③ 무한 용량(unbounded capacity): 큐의 길이가 무한

- 송신자는 결코 기다림 없이 메시지를 큐에 넣고 계속 수행

→ “자동 버퍼링”

* 유용량(nonzero capacity)의 경우, 송신자의 입장에서 메시지의 도달이 확인되지 않음

→ 수신을 확인하기 위해서는 명시적인 통신 필요

  P: send(Q, message);  Q: receive(P, message) ;

     receive(Q, message);    send(P, "acknowledgement");


▶ 그 밖의 특별한 경우

① 송신 프로세스가 결코 지연되지 않는 경우: 수신자가 이전의 메시지를 받기 전에 다른 메시지를 보내면 처음의 메시지는 유실됨

→ 메시지가 상실되지 않고 전달되고 송신자와 수신자가 동시에 메시지 버퍼를 조작하지 않는다는 것을 보장하기 위해 명백한 동기화 필요

② 송신 프로세스가 회신을 받을 때까지 지연되는 경우: ex) Thoth 운영체제

     P: send(Q, message)    ↔    Q: reply(P, message)

              ↓                            ↓

        송신자 P의 봉쇄              송신자 Q의 계속 수행 및 수신자 P의 재개


4.6.4 예외 조건(Exception Conditions)

“메시지 기법의 측면에서 오류 발생시 처리해야 하는 예외 조건”


4.6.4.1 프로세스 종료(Process Terminates)


▶ 메시지가 처리되기 전에 송신자나 수신자가 종료될 수 있음

① 결코 송신되지 않을 메시지를 기다리는 프로세스를 남기는 경우

예로써, 수신 프로세스 P가 종료된 송신 프로세스 Q로부터 메시지를 기다리는 경우

- 프로세스 P가 무한 봉쇄됨

- 시스템이 P를 끝내거나 Q의 종료를 알림

② 결코 수신되지 않을 메시지를 남기는 경우

예로써, 송신 프로세스 P가 종료된 수신 프로세스 Q에 송신하는 경우

- 자동 버퍼링의 경우: P 봉쇄 안됨 → 아무 문제없음

- 비버퍼링의 경우: P 봉쇄됨 → ①과 동일한 해결책 가능


4.6.4.2 메시지의 유실(Lost Messages)


               메시지 전송

      프로세스 P   →   프로세스 Q

                    ↖

                    하드웨어 or 통신라인 고장 ⇒ “메시지 유실”

▶ 메시지 유실의 취급 방법

- 운영체제가 이 사건을 탐지하고 메시지를 재전송

- 송신 프로세스가 이 사건을 탐지하고 원하는 경우에 메시지를 재전송

- 운영체제가 이 사건을 탐지하여 송신 프로세스에 알리면, 송신 프로세스는 원하는 대로 수행


▶ 메시지 유실의 탐지 방법: “타임아웃(time-out)”

- 운영체제나 프로세스가 송신된 메시지에 대해 반드시 뒤따르는 회신에 소요되는 시간 간격을 규정하고, 이 시간을 초과하면 유실된 것으로 간주하고 재 전송하는 방법

- 그러나, 실제로 유실된 것이 아니라 조금 오래 걸릴 수 있는데, 그로 인해 다중 복사가 발생할 수 있음(16장 참조)


4.6.4.3 훼손 메시지(Scrambled Message)


▶ 메시지는 전송 도중에 훼손될 수 있음: ex) 통신 채널의 잡음 등

- 탐지: 오류 검사 코드

- 해결: 유실된 메시지의 경우와 유사 → 일반적으로 운영체제가 재 전송함


4.6.5 실례: Mach


▶ 내용

- 카네기 멜론 대학에서 개발한 분산시스템을 위한 운영체제

- 메일박스(포트)에 의한 메시지 전송

- 시스템 호출도 메시지로 수행

- 각 태스크가 생성될 때마다 두 메일박스 생성

  1) 커널 메일박스(Kernel mailbox): 커널이 태스크와 통신하기 위해 사용

  2) 통지 메일박스(Notify mailbox): 커널이 사건 발생을 통지하기 위해 사용

- 메시지 전송을 위한 시스템 호출

  1) msg_send 호출: 메시지를 메일박스로 전송

  2) msg_receive 호출: 메시지를 수신

  3) msg_rpc 호출: 메시지 송신 후 회신 메시지를 기다리는 원격 프로시저 호출

- port_allocate 호출: 메일박스의 생성 및 메시지 큐를 위한 공간 할당

  → 소유권/수신권 발생: 양도 가능

- 메시지의 구성

  1) 고정 길이의 헤더 부분: 메시지 길이, 수신 메일박스명, 송신 메일박스명(회신용)

  2) 가변 길이의 자료 부분: 정형화된 자료의 리스트

- 메일박스가 만원일 때, 송신 스레드의 선택

  1) 여유공간이 생길 때까지 무한정 대기

  2) 최대 n 미리초 대기

  3) 전혀 기다리지 않고, 즉시 복귀

  4) 임시로 메시지를 캐시(cache)하는 방법

    - 메일박스가 만원일 때, 하나의 메시지에 한해서 운영체제가 보관하도록 넘길 수 있음

    - 그 메시지가 실제로 메일박스에 놓이게 되면, 송신자에게도 그 메시지를 되돌려 보내 알림

- port_status 호출: 주어진 메일박스의 메시지 수를 반환

- 송신자의 메시지를 포함하는 주소 공간을 수신자의 주소 공간에 매핑함으로써, 두 번의 메시지 전송(송신자 → 메일박스 → 수신자)을 피하고 있음


4.6.6 실례: Windows NT


▶ 내용

- 다중 운영 환경인 부 시스템을 지원: 응용 프로그램들이 메시지 전송 기법으로 부 시스템과 통신

  → 응용 프로그램들을 NT 부 시스템 서버의 클라이언트로 간주함

- NT의 메시지 전달 기능: 지역 프로시저 호출(Local Procedure Call; LPC) 기능

  → 두 프로세스간의 연결 설정을 위해 포트(메일박스) 객체를 사용

- 두 종류의 포트 사용: 연결 포트(connection port) & 통신 포트(communication port)

  → 실제로는 동일하나 사용 방법에 따라 다른 이름으로 사용

- 통신 작업:

1) 클라이언트는 부 시스템의 연결 포트 객체에 대한 핸들을 개방함

2) 클라이언트는 연결 요청을 보냄

3) 서버는 개인적인 두 통신 포트를 생성하고 클라이언트에게 그 중 하나에 대한 핸들을 반환

4) 클라이언트와 서버는 대응된 포트 핸들을 사용하여 메시지를 보내거나 회신(callback)하거나 응답을 기다림

- 세 가지 메시지 전달 기법

1) 포트의 메시지 큐를 사용하는 방법: 작은 메시지(256 바이트 이내) 전송

2) 섹션 객체(공유기억장치)를 사용하는 방법: 보다 큰 메시지 전송

3) quick LPC: 그래픽 함수와 같은 기본적인 함수의 실행시 사용








'시리즈 > OS' 카테고리의 다른 글

10. 파일 시스템 인터페이스(File System Interface)  (0) 2014.08.07
가상 기억장치(Virtual Memory)  (0) 2014.07.27
기억장치 관리(Memory Management)  (0) 2014.07.25
운영체제 - 교착 상태(Deadlocks)  (0) 2014.07.24
중앙처리장치 스케줄링(CPU Scheduling)  (0) 2014.07.17
Posted by MSNU






favicon

MADE FOR ALL

  • 태그
  • 링크 추가
  • 방명록

관리자 메뉴

  • 관리자 모드
  • 글쓰기
  • 분류 전체보기 (609)
    • 러시아어 (16)
    • myPPT (414)
    • 시리즈 (166)
      • OS (14)
      • 회계 (57)
      • 경제 (22)

카테고리

PC화면 보기 티스토리 Daum

티스토리툴바