[OS 공룡책] Chapter 3. 프로세스

본 포스트는 공룡책이라 불리는 Abraham Silberschatz, Peter B. Galvin, Greg GagneOperating System Concept 10th 을 바탕으로 작성하였습니다.

프로세스는 실행 중인 프로그램을 말하며, 현대의 컴퓨팅 시스템에서 작업의 단위이다.

3.1 프로세스 개념 (Process Concept)

운영체제의 주요 활동이 작업 처리인 시절에 많은 운영체제 이론 및 용어가 개발되었기 때문에 일부 적절한 경우 운영체제의 역할을 설명할 때 작업(job)을 사용한다.

3.1.1 프로세스 (The Process)

프로세스의 현재 활동의 상태는 프로그램 카운터 값과 프로세서 레지스터의 내용으로 나타낸다.

프로세스의 메모리 배치는 다음과 같다.

image

  • 텍스트(text) 섹션: 실행 코드
  • 데이터(data) 섹션: 전역 변수
  • 힙(heap) 섹션: 프로그램 실행 중에 동적으로 할당되는 메모리
  • 스택(stack) 섹션: 함수를 호출할 때 임시 데이터 저장장소

텍스트 및 데이터 섹션의 크기는 고정되기 때문에 프로그램 실행 시간 동안 크기가 변하지 않는다. 그러나 스택 및 힙 섹션은 프로그램 실행 중에 동적으로 줄어들거나 커질 수 있다.

  • 함수가 호출될 때마다 활성화 레코드가 스택에 푸시(push)
    • 활성화 레코드(activation record): 함수 매개변수, 지역 변수 및 복귀 주소를 포함
  • 함수에서 제어가 되돌아오면 스택에서 활성화 레코드 팝(pop)
  • 힙도 마찬가지로 메모리가 동적으로 할당됨에 따라 커지고 메모리가 시스템에 반환되면 축소

위의 그림과 같이 스택은 자라면서 밑으로, 힙은 자라면서 위로 서로의 방향으로 커지더라도 운영체제는 서로 겹치지(overlap) 않도록 해야 한다.

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

  • 프로그램: 명령어 리스트를 내용으로 가진 디스크에 저장된 파일(실행 파일, executable file)과 같은 수동적인 존재(passive entity)
  • 프로세스: 다음에 실행할 명령어를 지정하는 프로그램 카운터와 관련 자원의 집합을 가진 능동적인 존재(active entity)

실행 파일이 메모리에 적재될 때 프로그램은 프로세스가 된다.

3.1.2 프로세스 상태 (Process State)

프로세스의 상태는 부분적으로 그 프로세스의 현재의 활동에 따라서 정의된다. 아래의 그림은 상태들을 나타낸 상태 다이어그램(state diagram)이다.

image

  • 새로운(new): 프로세스가 생성 중
  • 실행(running): 명령어들이 실행 중
  • 대기(waiting): 프로세스가 어떤 이벤트(입출력 완료 또는 신호의 수신 같은)가 일어나기를 대기
  • 준비(ready): 프로세스가 프로세서에 할당되기를 대기
  • 종료(terminated): 프로세스의 실행이 종료

어느 한순간에 한 프로세서 코어에서는 오직 하나의 프로세스만이 실행된다.

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

각 프로세스는 운영체제에서 프로세스 제어 블록(process control block, PCB) 에 의해 표현된다. 아래의 그림은 PCB를 나타낸다.

image

  • 프로세스 상태: 새로운(new), 준비(ready), 실행(running), 대기(waiting), 또는 정지(halted) 상태 등
  • 프로그램 카운터: 이 프로세스가 다음에 실행할 명령어의 주소
  • CPU 레지스터들: 누산기(accumulator), 인덱스 레지스터, 스택 레지스터, 범용(general-purpose) 레지스터, 상태 코드(condition code) 정보를 포함
  • CPU-스케줄링 정보: 프로세스 우선순위, 스케줄 큐에 대한 포인터와 다른 스케줄 매개변수를 포함
  • 메모리 관리 정보: 운영체제에 의해 사용되는 메모리 시스템에 따라 기준(base) 레지스터와 한계(limit) 레지스터의 값, 페이지 테이블, 세그먼트 테이블 등과 같은 정보를 포함
  • 회계(accounting) 정보: CPU 사용 시간과 경과된 시간, 시간 제한, 계정 번호, 잡(job) 또는 프로세스 번호 등을 포함
  • 입출력 상태 정보: 이 프로세스에 할당된 입출력 장치들과 열린 파일의 목록 등을 포함

3.1.4 스레드 (Threads)

Chapter 4에서 자세하게 다룸

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

  • 다중 프로그래밍의 목적: CPU 이용을 최대화하기 위해 항상 어떤 프로세스가 실행되도록 한다.
  • 시분할(time-sharing)의 목적: 각 프로그램이 실행되는 동안 사용자가 상호 작용할 수 있도록 프로세스들 사이에서 CPU 코어를 빈번하게 교체한다.

이 목적을 달성하기 위해 프로세스 스케줄러(process scheduler) 는 코어에서 실행 가능한 여러 프로세스 중에서 하나의 프로세스를 선택한다.

현재 메모리에 있는 프로세스 수를 다중 프로그래밍 정도(degree of multiprogramming)라고 한다.

다중 프로그래밍 및 시간 공유의 목표를 균형 있게 유지하려면 프로세스의 일반적인 동작을 고려해야 한다.

  • I/O 바운드 프로세스: 계산에 소비하는 것보다 I/O에 더 많은 시간을 소비한다.
  • CPU 바운드 프로세스: 계산에 더 많은 시간을 사용하여 I/O 요청을 자주 생성하지 않는다.

3.2.1 스케줄링 큐 (Scheduling Queue)

아래의 그림은 프로세스 스케줄링의 일반적인 표현인 큐잉 다이어그램(queueing diagram)이다.

image

  1. 새 프로세스는 준비 큐(ready queue)에 놓인다. 프로세스는 실행을 위해 선택되거나 또는 디스패치(dispatch) 될 때까지 기다린다.
  2. 프로세스에 CPU 코어가 할당되고 실행 상태가 되면, 여러 이벤트 중 하나가 발생할 수 있다.
  • 프로세스가 I/O 요청을 공표한 다음 I/O 대기 큐(wait queue)에 놓일 수 있다.
    • 입출력 완료 후 다시 준비 큐로 돌아간다.
  • 프로세스는 새 자식(child) 프로세스를 만든 다음 자식의 종료를 기다리는 동안 대기 큐에 놓일 수 있다.
    • 자식의 종료 후 다시 준비 큐로 돌아간다.
  • 인터럽트 또는 타임 슬라이스가 만료되어 프로세스가 코어에서 강제로 제거되어 준비 큐로 돌아갈 수 있다.
  1. 종료 될 때까지 1, 2 반복한다.
  2. 종료 시점에 모든 큐에서 제거되고 PCB 및 자원이 반환된다.

3.2.2 CPU 스케줄링 (CPU Scheduling)

Chapter 5에서 자세하게 다룸

3.2.3 문맥 교환 (Context Switch)

인터럽트가 발생하면 시스템은 인터럽트 처리가 끝난 후에 문맥(context)를 복구할 수 있도록 현재 문맥을 저장할 필요가 있다.

문맥은 프로세스의 PCB에 표현되며, 문맥은 CPU 레지스터의 값, 프로세스의 상태, 메모리 관리 정보 등을 포함한다.

문맥 교환(context switch) 은 CPU 코어를 다른 프로세스로 교환하기 위해 이전의 프로세스의 상태를 보관하고 새로운 프로세스의 보관된 상태를 복구하는 작업이다.

  • 저장 작업(state save): CPU의 현재 상태를 저장
  • 복구 작업(state restore): 연산을 재개하기 위해 저장해둔 상태를 복구

3.3 프로세스에 대한 연산 (Operation on Processes)

3.3.1 프로세스 생성 (Process Creation)

실행되는 동안 프로세스는 여러 개의 새로운 프로세스들을 생성할 수 있다.

  • 부모(parent) 프로세스: 생성하는 프로세스
  • 자식(child) 프로세스: 생성되는 프로세스

자식 프로세스들을 각각 다시 다른 프로세스들을 생성할 수 있으며, 그 결과 프로세스의 트리(tree)를 형성한다.

UNIX, Linux 및 Windows와 같은 대부분의 현대 운영체제들은 유일한 프로세스 식별자(pid, process identifier)를 사용하여 프로세스를 구분하는데, pid는 시스템의 각 프로세스에 고유한 값(보통 정수)을 가지도록 할당된다.

자식 프로세스는 필요한 자원을 운영체제로부터 직접 얻거나, 부모 프로세스가 가진 자원의 부분 집합만을 사용하도록 제한될 수 있다.

프로세스가 새로운 프로세스를 생성할 때, 두 프로세스를 실행시키는 방법:

  • 부모는 자식과 병행하게 실행을 계속한다.
  • 부모는 일부 또는 모든 자식이 실행을 종료할 때까지 기다린다.

자식 프로세스들의 주소 공간 측면에서 볼 때 방법:

  • 자식 프로세스는 부모 프로세스의 복사본이다.
  • 자식 프로세스가 자신에게 적재될 새로운 프로그램을 가지고 있다.

image

fork() 시스템 콜 호출 시:

  • 자식 프로세스 생성
  • 자식 프로세스는 부모 프로세스의 주소 공간의 복사본으로 구성
  • 자식 프로세스의 fork() return 값 = 0
  • 부모 프로세스의 fork() return 값 = 자식 프로세스의 pid

fork() 다음 exec() 시스템 콜 호출 시:

  • 자신의 메모리 공간을 새로운 프로그램으로 교체
  • 이진 파일을 메모리로 적재(load) 후 그 프로그램의 실행을 시작
    • 여전히 자식과 부모는 통신 가능
    • 서로 다른 프로세스간 통신을 위해 많이 사용
  • 그 후 부모는 다른 많은 자식을 생성할 수 있으며, 자식이 실행하는 동안 할 일이 없다면 자식이 종료될 때까지 준비 큐에서 자신을 제거하기 위해 wait() 시스템 콜을 한다.

3.3.1 프로세스 종료 (Process Termination)

프로세스가 마지막 문장의 실행을 끝내고, exit() 시스템 콜을 사용하여 운영체제에 자신의 삭제를 요청하면 종료한다. 이 시점에서 프로세스는 자신을 기다리고 있는 부모 프로세스에 상태 값을 반환하며 프로세스의 모든 자원이 할당 해제되고 운영체제로 반납된다.

한 프로세스가 적당한 시스템 콜을 통해서 다른 프로세스의 종료를 유발할 수 있다.

  • 종료될 프로세스의 부모만이 호출 가능
  • 자식의 pid를 알아야 가능
    • fork()의 반환값으로 알 수 있다.

부모가 자식을 종료시키는 이유:

  • 자식이 자신에게 할당된 자원을 초과하여 사용할 때
    • 부모가 자식의 상태를 확인할 수 있어야 한다.
  • 자식에게 할당된 태스크가 더 이상 필요 없을 때
  • 부모가 exit을 하는데, 운영체제는 부모가 exit 한 후에 자식이 계속 실행하는 것을 허용하지 않을 경우

몇몇 시스템에서는 부모가 종료한 이후에 자식 프로세스가 존재할 수 없기 때문에 프로세스가 종료되면 모든 자식 프로세스도 종료시키는 연쇄식 종료(cascading termination)을 운영체제가 시행한다.

종료되었지만 부모 프로세사가 아직 wait()을 호출하지 않은 프로세스를 좀비(zombie) 프로세스라고 한다.

  • 부모가 wait()을 호출하면 좀비프로세스의 자원이 운영체제에 반환된다.

부모 프로세스가 wait()을 호출하지 않고 종료된다면 그 자식 프로세스는 고아(orphan) 프로세스가 된다.

  • UNIX는 고아 프로세스의 새로운 부모 프로세스로 init 프로세스를 지정한다.
    • init 프로세스는 주기적으로 wait()을 호출하여 고아 프로세스들의 종료 상태를 수집하고 자원들을 운영체제로 반환한다.
  • Linux는 init을 systemd로 대체하여 init의 역할을 다 수행하지만, 고아 프로세스는 다른 프로세스가 관리하도록 허용한다.
    • 고아 프로세스의 조상 중에 고아 프로세스 처리기(handler)가 있는 데몬(daemon) 프로세스가 있다면 그 프로세스가 처리하고 그렇지 않다면 결국에 계속 위로 타고 올라가 최상위에 있는 systemd가 처리한다.

3.4 프로세스 간 통신 (Interprocess Communication)

실행 중인 다른 프로세스들과 데이터를 공유하지 않는 프로세스는 독립적(independent)이고, 다른 프로세스들에 영향을 주거나 받는가면 이는 협력적인(cooperating) 프로세스들이다.

프로세스 협력을 허용하는 환경을 제공하는 이유:

  • 정보 공유(information sharing): 여러 응용 프로그램이 동일한 정보가 필요할 때, 그러한 정보를 병행적으로 접근할 수 있는 환경 제공
  • 계산 가속화(computation speedup): 특정 태스크를 빨리 실행하기 위해 서브태스크로 나누어 각각 다른 서브태스크들과 병렬로 실행
    • 복수 개의 처리 코어(processing core)를 가진 경우에만 가능
  • 모듈성(modularity): 시스템 기능을 별도의 프로세스들 또는 스레드들로 나누어 모듈식 형태로 구성하기 원할 경우

프로세스 간 통신(interprocess communication, IPC) 기법은 협력적 프로세스들이 서로 데이터를 보내거나 받을 수 있게 한다.

image

  • 공유 메모리(shared memory)
    • 프로세스들에 의해 공유되는 메모리의 영역이 구축
    • 그 영역에 데이터를 읽고 쓰고 함으로써 정보 교환
    • 메모리 영역 구축할 때만 시스템 콜이 필요하고 구축된 후의 모든 접근은 일반적인 메모리 접근으로 취급되어 커널의 도움이 필요 없다.
  • 메세지 전달(message passing)
    • 프로세스들 사이에 교환되는 메세지를 통하여 정보 교환
    • 통상 시스템 콜을 사용
      • 커널 간섭 등의 부가적인 시간 소비 작업이 필요

3.5 공유 메모리 시스템에서의 프로세스 간 통신 (IPC in Shared-Memory Systems)

일반적으로 운영체제는 한 프로세스가 다른 프로세스의 메모리에 접근하는 것을 금지한다. 공유 메모리는 둘 이상의 프로세스가 이 제약 조건을 무시한다는 전제 하에 이루어진다.

프로세스들은 동시에 공유메모리에서 동일한 위치에 덮어쓰지 않도록 해야 데이터 손실을 막을 수 있다.

  • 생산자(producer) 프로세스: 정보를 생산
  • 소비자(consumer) 프로세스: 정보를 소비

생산자와 소비자 프로세스들이 병행으로 실행되도록 하려면, 생산자가 정보를 채워넣고 소비자가 소모할 수 있는 항목들의 버퍼(buffer)가 반드시 사용 가능해야 한다. 생산자와 소비자가 반드시 동기화되어야 생산되지도 않은 항목들을 소비자가 소비하려 시도하지 않을 것이다. 그러기 위해 두 가지 유형의 버퍼가 사용된다.

  • 무한 버퍼(unbounded buffer)
    • 버퍼의 크기에 실질적인 한계가 없다.
    • 생산자는 항상 새로운 항목을 생산할 수 있다.
    • 소비자는 새로운 항목을 기다려야만 할 수도 있다.
  • 유한 버퍼(bounded buffer)
    • 버퍼의 크기가 고정되어 있다.
    • 버퍼가 비어있다면 소비자는 반드시 대기한다.
    • 모든 버퍼가 채워져 있으면 생산자가 대기한다.

3.6 메세지 전달 시스템에서의 프로세스 간 통신 (IPC in Message-Passing Systems)

메세지 전달 방식은 동일한 주소 공간을 공유하지 않고도 프로세스들이 통신을 하고, 그들의 동작을 동기화할 수 있도록 허용하는 기법이다.

메세지 전달 시스템은 최소한 두 가지 연산인 send(message)와 receive(message)를 제공한다.

  • 고정 길이 메세지: 시스템 수준의 구현이 직선적이지만 프로그래밍 작업이 힘들어진다.
  • 가변 길이 메세지: 시스템 수준의 구현이 복잡해지지만 프로그래밍 작업이 간단해진다.

프로세스끼리 통신을 원하면 통신 연결(communication link)이 설정되어야 한다.

  • 직접 or 간접 통신: 서로를 가르키는 방법에 따른 구분
  • 동기식 or 비동기식 통신: 동기화를 하는 방법에 따른 구분
  • 자동 or 명시적 버퍼링: 버퍼 크기를 조정하는 방법에 따른 구분

통신 연결은 세 가지 양자택일 중 하나씩 골라 구성한다. (ex: 직접적이며 비동기식 동기화와 명시적 버퍼링을 가진 통신연결)

3.6.1 명명 (Naming)

  • 직접 통신
    • 수신자 또는 송신자의 이름을 명시해야 한다.
    • 대칭 프리미티브
      • send(P, message): 프로세스 P에 메세지를 전송
      • receive(Q, message): 프로세스 Q로부터 메세지를 수신
    • 비대칭 프리미티브
      • send(P, message): 프로세스 P에 메세지를 전송
      • receive(id, message): 임의의 프로세스로부터 메세지를 수신
        • id는 통신을 발생시킨 프로세스의 이름으로 설정
    • 특징
      • 통신을 원하는 각 프로세스의 쌍들 사이에 연결이 자동으로 구축한다.
      • 프로세스들은 통신하기 위해 상대방의 신원(identity)만 알면 된다.
      • 연결은 정확히 두 프로세스 사이에만 연관된다.
      • 통신하는 프로세스들의 각 쌍 사이에는 정확하게 하나의 연결이 존재해야한다.
      • 프로세스를 지정하는 방식때문에 모듈성을 제한한다는 것이 단점이다.
        • 프로세스의 이름을 바꾸면 모든 다른 프로세스 지정 부분을 검사할 필요가 있을 수 있다.
  • 간접 통신
    • 메세지들은 메일박스(mailbox) 또는 포트(port)로 송신되고 그것으로부터 수신된다.
    • 메일박스는 고유의 id를 가진다.
    • 프리미티브
      • send(A, message): 메세지를 메일박스 A로 송신
      • receive(A, message): 메세지를 메일박스 A로부터 수신
    • 특징
      • 두 프로세스들이 공유 메일박스를 가질 때만 서로 통신할 수 있다.
      • 연결은 두 개 이상의 프로세스들과 연관될 수 있다.
      • 통신하고 있는 각 프로세스 사이에는 다수의 서로 다른 연결이 존재할 수 있고, 각 연결은 하나의 메일박스에 대응된다.
    • 다수의 프로세스가 하나의 메일박스를 공유할 때, 어떤 메세지를 수신할 지 정하는 방법:
      • 하나의 링크는 최대 두 개의 프로세스와 연관되도록 허용한다
      • 한순간에 최대로 하나의 프로세스가 receive() 연산을 실행하도록 허용한다
      • 어느 프로세스가 메세지를 수신할 것인지 시스템이 임의로 선택하도록 한다.
        • 시스템이 어느 프로세스가 수신할 것인지를 선택하는 알고리즘을 정의할 수 있다.
        • 시스템은 송신자에게 수신자를 알려 줄 수 있다.
    • 메일박스 owned by 프로세스
      • 각 메일박스가 고유한 소유자를 가지고 있기 때문에, 소유자와 사용자를 구분할 수 있어 메세지를 어느 프로세스가 수신할 지에 대한 혼란이 없다.
        • 소유자: 메일박스로부터 메세지를 수신만 가능한 프로세스
        • 사용자: 메일박스에 메세지를 송신만 가능한 프로세스
      • 메일박스를 소유하고 있는 프로세스가 종료할 때 메일박스가 사라진다.
        • 그 메일박스로 송신하는 모든 프로세스가 메일박스가 사라진 사실을 반드시 통보받아야 한다.
    • 메일박스 owned by 운영체제
      • 독립적이며 어떤 특정한 프로세스에 예속되지 않는다.
      • 운영체제는 한 프로세스에 다음을 할 수 있도록 허용하는 기법을 반드시 제공해야 한다.
        • 새로운 메일박스를 생성한다.
        • 메일박스를 통해 메세지를 송신하고 수신한다.
        • 메일박스를 삭제한다.
      • 새로운 메일박스를 생성하는 프로세스가 default로 메일박스의 소유자가 되며, 소유권과 수신 특권은 적절한 시스템 콜을 통해 다른 프로세스에 전달될 수 있다.

3.6.2 동기화 (Synchronization)

  • 봉쇄형(blocking)
    • 보내기(send): 송신하는 프로세스는 메세지가 수신 프로세스 또는 메일박스에 의해 수신될 때까지 봉쇄된다.
    • 받기(receive): 메세지가 이용 가능할 때까지 수신 프로세스가 봉쇄된다.
  • 비봉쇄형(nonblocking)
    • 보내기(send): 송신하는 프로세스가 메세지를 보내고 작업을 재시작한다.
    • 받기(receive): 송신하는 프로세스가 유효한 메세지 또는 널(null)을 받는다.

3.6.3 버퍼링 (Buffering)

  • 무용량(zero capacity)
    • 큐의 최대 길이가 0
    • 링크는 자체 안에 대기하는 메세지들을 가질 수 없다.
    • 송신자는 수신자가 메세지를 수신할 때까지 기다려야 한다.
  • 유한 용량(bounded capacity)
    • 큐는 유한한 길이 n을 가진다.
    • 최대 n개의 메세지가 들어 있을 수 있다.
    • 큐가 만원이 아니라면 메세지는 큐에 놓이고, 만원이라면 송신자는 공간 이용이 가능할 때까지 봉쇄된다.
  • 무한 용량(unbounded capacity)
    • 큐는 잠재적으로 무한한 길이를 가진다.
    • 메세지들이 얼마든지 큐 안에서 대기 가능
    • 송신자는 절대 봉쇄되지 않는다.

3.7 IPC 시스템의 사례 (Examples of IPC Systems)

3.7.1 POSIX 공유 메모리 (POSIX Shared Memory)

POSIX는 공유 메모리를 위한 API를 제공한다.

  • mmap() 함수로 공유 메모리 객체를 포함하는 메모리-사상(memory-mapped)파일을 구축한다.

3.7.2 Mach 메세지 전달 (Mach Message Passing)

Mach 운영체제는 프로세스 간 통신의 기본 형태로 메세지 전달을 사용한다.

  • 포트(port)라고 하는 메일박스로 메세지를 주고 받는다
    • 포트는 크기가 정해져 있고 단방향이다.

3.7.3 Windows (Windows)

  • 고급 로컬 프로시저 호출 설비(ALPC, advanced local procedure call facility)
    • Windows의 메세지 전달 설비
    • 연결 포트(connection port)와 통신 포트(communication port)를 사용한다.

3.7.4 파이프 (Pipes)

파이프(pipes) 는 두 프로세스가 통신할 수 있게 하는 전달자로서 동작한다.

  • 파이프를 구현하기 위한 제약
    • 파이프가 단방향 통신 또는 양방향 통신을 허용하는가?
    • 양방향 통신이 허용된다면 반이중 방식인가, 전이중 방식인가?
      • 반이중 방식(half duplex): 한순간에 한 방향 전송 가능
      • 전이중 방식(full duplex): 동시에 양방향 데이터 전송 가능
    • 통신하는 두 프로세스 간에 부모-자식과 같은 특정 관계가 존재해야만 하는가?
    • 파이프는 네트워크를 통하여 통신이 가능한가, 아니면 동일한 기계 안에 존재하는 두 프로세스끼리만 통신할 수 있는가?

3.7.4.1 일반 파이프 (Ordinary Pipes)

일반 파이프는 생산자-소비자 형태로 두 프로세스 간의 통신을 허용한다.

  • 생산자는 파이프의 한 종단(쓰기 종단)에 쓴다.
  • 소비자는 파이프의 다른 종단(읽기 종단)에서 읽는다.

한쪽으로만 데이터를 전송할 수 있으며 오직 단방향 통신만을 가능하게 한다.

  • 양방향 통신이 필요하다면 각각 다른 방향으로 데이터를 전송할 수 있는 두 개의 파이프를 사용해야 한다.

image

파이프를 생성한 프로세스 이외에는 접근할 수 없다.

  • 부모 프로세스가 파이프를 생성하고 fork()로 생성한 자식 프로세스와 통신하기 위해 사용한다.
    • 자식 프로세스는 열린 파일을 부모로부터 상속받기 때문

Windows 시스템의 일반 파이프는 익명 파이프(anonymous pipe) 라고 불린다.

동일한 기계상의 두 프로세스끼리만 통신이 가능하다.

3.7.4.1 지명 파이프 (Named Pipes)

통신은 양방향으로 가능하며 부모-자식 관계도 필요로 하지 않는다.

지명 파이프가 구축되면 여러 프로세스들이 이를 사용하여 통신할 수 있다.

통신 프로세스가 종료하더라도 지명 파이프는 계속 존재한다.

UNIX에서는 FIFO라고 부른다.

  • 양방향 통신을 허용하지만 반이중 전송만이 가능하다.
  • 데이터가 양방향으로 전송될 필요가 있다면 보통 2개의 FIFO가 사용된다.
  • 동일한 기계 내에 존재해야 한다.
  • 바이트 단위 통신만을 허용한다.

Windows도 지명 파이프를 지원한다.

  • 전이중 통신을 허용한다
  • 같은 기계 또는 다른 기계상에 존재할 수 있다.
  • 바이트 또는 메세지 단위 데이터의 전송을 허용한다.

3.8 클라이언트 서버 환경에서의 통신 (Communication in Client–Server Systems)

클라이언트 서버에서 사용할 수 있는 두 가지 다른 통신 전략이 있다.

3.8.1 소켓 (Socket)

소켓은 통신의 극점(endpoint)을 뜻한다.

  • 두 프로세스가 네트워크상에서 통신을 하려면 양 프로세스마다 하나씩, 총 두 개의 소켓이 필요해진다.
  • 각 소켓은 IP 주소와 포트 번호 두 가지를 접합(concatenate)해서 구별한다.
  • 일반적으로 클라이언트-서버 구조를 사용한다.

    • 클라이언트(client): 지정된 포트에 요청(request) 메세지를 보낸다.
    • 서버(server): 요청이 수신되면 서버는 연결 요청을 수락한다.
  • 소켓을 이용한 통신은 분산된 프로세스 간에 널리 사용되고 효율적이기는 하나 너무 낮은 수준이다.
    • 스레드 간에 구조화되지 않은 바이트 스트림만을 통신하도록 하기 때문
    • 원시적인 바이트 스트림 데이터를 구조화하여 해석하는 일은 클라이언트와 서버의 책임이 된다.

3.8.2 원격 프로시저 호출 (Remote Procedure Calls, RPC)

RPC는 다른 컴퓨터에 있는 프로세스에서 함수를 호출할 수 있는 방식이다.

Leave a comment