Study/OS

[운영체제] 3. Process

harchiving 2025. 4. 17. 15:36
반응형
해당 내용은 공룡책(Operating System Concepts 10th Ed. : Abraham Silberschatz, Peter Baer Galvin, Greg Gagne)과 대학 강의를 기반으로 재구성하여 정리한 공부 내용입니다.

1. 프로세스 개념(Process Concept)

CPU 활동들에 대하여 일괄처리 시스템에서는 작업(job), 이후 시분할 시스템에서는 사용자 프로그램 또는 태스크(task)라 하였고, 현재에는 이 모든 활동에  대해 프로세스라 한다.

 

프로세스(The Process)

프로세스: 실행 중인 프로그램

프로세스의 현재 활동 상태: 프로그램 카운터 값과 프로세서 레지스터 내용으로 표현

프로세스의 메모리 배치:

  • 텍스트 섹션: 실행 코드
  • 데이터 섹션: 전역 변수, 정적 변수
  • 힙 섹션: 프로그램 실행 중에 동적으로 할당되는 메모리
  • 스택 섹션: 함수를 호출할 때 임시 데이터 저장장소(ex. 함수 매개변수, 복귀 주소 및 지역 변수)

텍스트 및 데이터 섹션의 크기는 고정(실행 시간 동안 크기 불변), 스택 및 힙 섹션은 서로의 방향으로 동적으로 공간 사용

 

프로그램 ≠ 프로세스

프로그램: 명령어 리스트를 내용으로 가진 디스크에 저장된 파일(실행 파일)과 같은 수동적인 존재(passive entity)

프로세스: 다음에 실행할 명령어를 지정하는 프로그램 카운터와 관련 자원의 집합을 가진 능동적인 존재(active entity)

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

 

실행 파일을 메모리에 적재하는 일반적인 방식

- 실행 파일을 나타내는 아이콘을 GUI 상 마우스로 더블 클릭하는 방식

- 명령어 라인 상에서 파일 이름을 입력하는 방식

 

여러 사용자가 프로그램의 서로 다른 복사본 실행 가능 → 하나의 프로그램은 여러 프로세스가 될 수 있다.

 

스택 세그먼트 vs 스택 프레임

* 세그먼트(segment): 메모리를 관리하는 논리적인 단위

스택 세그먼트: 프로세스의 메모리 중 스택을 구현하는 부분 → 스택 프레임의 컨테이너 역할

스택 프레임: 하나의 함수 호출에 해당하는 메모리 블록. 지역 변수, 함수에 전달된 인자, 반환 주소, CPU 레지스터(스택 포인터, 베이스 포인터 등) 정보를 가짐.  → 스택 세그먼트 안에서 개별적 함수의 실행 컨텍스트 관리

 

프로세스 상태(Process State)

 

프로세스는 실행되면서 부분적으로 그 프로세스의 현재 활동에 따라서 상태가 변한다.

OS 프로세서 스케줄러가 선정한 작업(프로세스)의 상태를 변화시키며 프로세스의 생성에서 종료까지의 과정을 수행하게 한다.

  • new: 프로세스 생성 중. 아직 메모리에 완전히 로드되지 않았거나 초기화가 진행 중인 상태
  • running: 명령어들이 실행 중. 프로세스가 실제로 CPU를 사용하여 명령어를 실행하고 있는 상태
  • waiting: 프로세스가 어떤 이벤트가 일어나기를 기다림
  • ready: 프로세스가 프로세서에 할당되기를 기다림
  • terminated: 프로세스의 실행이 종료됨

 

Waiting 사유

1. 입출력(I/O) 작업 요청

디스크 읽기/쓰기: 파일 시스템에서 데이터를 읽거나 쓰는 작업을 요청했을 때

네트워크 통신: 네트워크를 통해 데이터를 보내거나 받을 떄, 상대방 시스템의 응답을 기다릴 때

사용자 입력 대기: 키보드 입력, 마우스 클릭 등 사용자로부터 입력을 기다리는 동안 대기할 때

프린터 등 주변 장치와의 통신: 프린터로 출력을 보내거나 다른 주변 장치와 통신하는 동안 해당 작업이 완료되기를 기다릴 때

 

2. 특정 이벤트

다른 프로세스의 종료: 부모 프로세스가 자식 프로세스의 종료를 기다릴 때

자원 획득 대기: 특정 공유 자원(ex. 메모리, 파일, 하드웨어 장치)이 현재 다른 프로세스에 의해 사용 중이어서 해당 자원이 해제될 때까지 대기할 때

신호(signal) 대기

 

3. sleep

자발적인 대기

 

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

프로세스 제어 블록(태스크 제어 블록): 특정 프로세스와 연관된 여러 정보 수록. OS에서 프로세스를 관리할 때 가장 기본이 되는 자료 구조. 프로세스 상태 천이할 때 PCB 정보도 항상 갱신

 

프로세스 vs PCB

프로세스는 자원 할당, 상태 관리 등이 필요한 대상

PCB는 프로세스 전반 정보를 저장하는 자료 구조

→ 프로세스의 신분증 같은 역할: 운영체제가 프로세스를 다루는 모든 과정에서 참조하고 업데이트하는 핵심 데이터 구조

  • 프로세스 상태: new, ready, running, waiting, halted 상태 등
  • 프로그램 카운터: 해당 프로세스가 다음에 실행할 명령어의 주소를 가리킴
  • CPU 레지스터들: 나중에 프로세스가 다시 스케줄될 때 이어서 올바르게 실행되도록 인터럽트 발생 시 저장해야 함. accumulator, 인덱스 레지스터, 스택 레지스터, 범용 레지스터들과 상태 코드 정보가 포함.
  • CPU 스케줄링 정보: 프로세스 우선순위, 스케줄 큐에 대한 포인터와 다른 스케줄 매개변수 포함
  • 메모리 관리 정보: 운영체제가 사용하는 메모리 시스템에 따라 베이스 레지스터와 리미트 레지스터의 값, 페이지 테이블 또는 세그먼트 테이블 등과 같은 정보 포함
  • 회계 정보: CPU 사용 시간과 시작 후 경과된 clock 시간, 시간 제한, 계정 벙보, 프로세스 번호 등 포함
  • 입출력 상태 정보: 해당 프로세스에 할당된 입출력 장치들과 열린 파일 목록 등 포함

 

스레드(Threads)

지금까지 논의한 프로세스 모델 = 프로세스가 단일의 실행 스레드를 실행하는 프로그램(중량 프로세스, HWP; Heavy Weight Process. 스레드 하나에 프로세스 하나인 경우)

현대 운영체제는 한 프로세스가 다수의 실행 스레드를 가질 수 있도록 허용 → 프로세스가 한 번에 하나 이상의 일을 수행할 수 있도록 허용(경량 프로세스, LWP;Light Weight Process. 프로세스 자원을 공유하고 실행 기록만 별도 관리)

즉 여러 스레드가 병렬로 실행 가능

스레드 지원 시스템에서 PCB는 각 스레드에 관한 정보를 포함하도록 확장됨


2. 프로세스 스케줄링(Process Scheduling)

멀티 프로그래밍: CPU 이용을 최대화하는 목적, 항상 어떤 프로세스가 실행되도록 함. 메모리에 여러 프로그램 동시 유지.

시분할(Time Sharing): 각 프로그램이 실행되는 동안 사용자가 상호작용할 수 있도록 프로세스들 사이에서 CPU 코어를 빈번하게 교체. 시스템이 여러 사용자나 프로세스 간에 CPU 시간을 공정하게 분배하려는 개념.

→ 각 프로세스는 정해진 시간(Time slice)동안만 실행되고, 다른 프로세스로 전환

 

프로세스 스케줄러: 코어에서 실행 가능한 여러 프로세스 중 하나의 프로세스를 선택

각 CPU 코어는 한 번에 하나의 프로세스를 실행한다. → 다중 코어 시스템은 한 번에 여러 프로세스 실행 가능

 

프로세스의 일반적인 동작에 따라

I/O 바운드 프로세스: 계산에 소비하는 것보다 I/O에 더 많은 시간을 소비하는 프로세스. CPU < I/O 가용성에 의존.

CPU 바운드 프로세스: 계산에 더 많은 시간을 사용해 I/O 요청을 자주 생성하지 않음. CPU 속도에 의해 성능 결정.

 

스케줄링 큐

Job queue: 스세템에서 모든 프로세스의 집합

Ready queue: 메인 메모리에서 실행하려고 준비 또는 대기 중인 모든 프로세스의 집합

Device queues: I/O 장치를 위해 대기 중인 프로세스의 집합

프로세스는 수명 주기 동안 준비 큐와 다양한 대기 큐를 옮겨다닌다.

 

프로세스가 시스템에 들어가면 Ready queue에 들어가 준비 상태가 되어 CPU 코어에서 실행되기를 기다린다.

I/O 완료와 같이 특정 이벤트가 발생하기를 기다리는 프로세스는 wait queue에 삽입된다.

→ CPU가 특정 프로세스의 입출력 작업을 기다리는 동안 유휴 상태에 머무는 것을 방지하고, ready queue에 있는 다른 프로세스에게 CPU를 할당하여 전체적인 처리량을 높인다.

 

큐잉 다이어그램

 

CPU 스케줄링(CPU Scheduling)

CPU 스케줄러: ready queue에 있는 프로세스 중 선택된 하나의 프로세스에 CPU 코어를 할당하는 역할

메모리가 초과 사용되어 가용공간을 확보해야 할 때 스와핑을 사용하기도 함.

 

문맥 교환(Context Switch)

시스템은 인터럽트 처리가 끝난 후 문맥을 복구할 수 있도록 현재 실행 중인 프로세스의 현재 문맥을 저장해야 함

→ 프로세스를 중단했다가 재개하는 작업

유저 모드/커널 모드에 상관없이 CPU의 현재 상태를 저장하는 작업을 수행하고, 커널 인터럽트 핸들러로 점프해 이벤트를 처리 후 연산을 재개하기 위하여 상태 복구 작업을 수행한다.

커널은 과거 프로세스의 문맥을 PCB에 저장하고, 실행이 스케줄된 새로운 프로세스의 저장된 문맥을 복구한다.

 

또는 스케줄러 결정에 의해 필요 시(우선 순위나 타임 슬라이스가 종료되었을 때) 다른 프로세스에게 CPU를 배정할 때 발생.

 

문맥 교환(Context Switch): CPU 코어를 다른 프로세스로 교환할 때 이전의 프로세스의 상태를 보관하고 새로운 프로세스의 보관된 상태를 복구하는 작업

 

Context Switching Overhead

Context switch time은 순수한 오버헤드이다; 문맥 교환이 진행될 동안 시스템은 아무런 유용한 일을 하지 못함

해당 시간은 하드웨어의 지원에 크게 좌우된다. (Time dependent on hardware support)

메모리 속도, 레지스터 수, 특수 명령어의 유무에 따라 다름.

저장해야 할 레지스터 개수가 많을 수록, 메모리 액세스가 느릴 수록(PCB 읽고 쓰는 데) 시간이 증가.

일부 프로세서는 여러 개의 레지스터 집합을 제공한다. (다중 컨텍스트가 한 번에 로드될 수도 있음)

운영체제가 복잡할수록 문맥 교환 시 해야 할 작업의 양이 더 많아진다.

불필요한 문맥 교환 감소가 운영체제 설계의 주요 목표 → Soultion: Thread!


3. 프로세스에 관한 연산(Operation on Processes)

프로세스 생성(Process Creation)

운영체제는 프로세스 생성 및 종료를 위한 기법을 제공해야 한다.

부모 프로세스가 자식 프로세스를 생성하고, 이는 다시 다른 프로세스들을 생성하여 프로세스의 트리를 형성할 수 있다.

현대 운영체제들은 프로세스를 정수로 된 유일한 process identifier(pid)를 사용하여 구분한다.

 

Linux의 프로세스 트리

 

init(pid=1) 프로세스가 모든 프로세스의 뿌리

시스템이 필요한 각종 서비스(데몬) 프로세스를 생성

 

부모와 자식 프로세스 간 자원 공유 옵션: 1) 모두 공유 2) 부모 자원의 부분 집합만 공유 3) 공유X

실행 옵션: 1) 부모와 자식 프로세스 동시(병행하게) 실행 2) 자식 프로세스가 끝날 때까지 부모 프로세스 대기

주소 공간: 1) 자식 프로세스가 부모 프로세스의 복사본 2) 자식 프로세스가 자신에게 로드될 새로운 프로그램 보유

 

UNIX의 예시

 

 

fork() 시스템 콜: 새로운 프로세스 생성 - 원래 프로세스의 주소 공간의 복사본으로 구성

PCB를 포함한 부모 프로세스 영역(메모리)의 대부분이 자식 프로세스에 복사됨 =Copy-On-Write(COW)

 

exec() 시스템 콜: 자신의 메모리 공간을 새로운 프로그램으로 교체

기존 프로세스에서 프로세스는 그대로 둔 채 내용만 바꿈

fork()를 사용하여 별도 프로세스를 생성하는 C 프로그램 / WINDOW API를 이용한 새로운 프로세스의 생성

 

프로세스 종료(Process Termination)

프로세스가 마지막 문장의 실행을 끝내고, exit 시스템 콜을 사용하여 운영체제에 자신의 삭제를 요청하면 종료한다.

자식 프로세스는 자신을 기다리고 있는 부모 프로세스에 wait 시스템 콜을 통해 상태 값(자식 PID나 종료 코드)을 반환할 수 있다.

프로세스의 모든 자원(물리/가상 메모리, 열린 파일, 입출력 버퍼 등)이 할당 해제되고 운영체제로 반납된다.

 

부모 프로세스는 자식 중 하나의 실행을 종료할 수 있다. (TerminateProcess(), Kill())

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

몇몇 시스템에서는 부모 프로세스가 종료한 이후 자식 프로세스가 존재할 수 없다.

연쇄식 종료(cascading termination): 운영체제가 그로부터 비롯된 모든 자식 프로세스들을 종료시킴

 

좀비(zombie) 프로세스: 종료되었지만 부모 프로세스가 아직 wait() 호출을 하지 않은 프로세스

부모가 wait()을 호출하면 좀비 프로세스의 프로세스 식별자와 프로세스 테이블의 해당 항목이 운영체제에 반환된다.


4. 프로세스 간 통신(Interprocess Communication)

운영체제 내에서 실행되는 병행 프로세스들은 독립적이거나 협력적인 프로세스들일 수 있다.

독립적인 프로세스: 프로세스가 시스템에서 실행 중인 다른 프로세스들과 데이터를 공유하지 않는 프로세스

협력적인 프로세스: 프로세스가 시스템에서 실행 중인 다른 프로세스들에 영향을 주고 받는 경우(=자료를 공유)

프로세스 협력을 허용하는 환경을 제공하는 이유: information sharing, computation speedup, modularity

 

협력적 프로세스들프로세스 간 통신(Interprocess communication, IPC)이 필요하다.

IPC의 두 가지 모델: 1) Shared memory(공유 메모리), 2) Message passing(메시지 전달)

(a) 메시지 전달: 프로세스들이 메시지를 교환함으로써 통신함. 메시지 큐, 파이프 등이 있어 프로세스들이 공유 변수 없이 통신 가능함.

 

(b) 공유 메모리: 프로세스들이 공유 데이터에 대해 직접적인 접근함. 빠른 데이터 접근 제공, but 동기화 문제 관리 필요.

 

*멀티 프로세스 구조 - Chrome 브라우저

많은 웹사이트들은 단일 프로세스로 렌더링되어, 탭 중 하나라도 고장나면 전체 브라우저가 고장난다.

하지만 구글의 크롬 웹 브라우저는 3가지 타입의 프로세스로 다중 프로세스 구조를 활용하여 문제를 해결하였다.

1) 브라우저 프로세스는 UI, 디스크, 네트워크 입출력을 관리한다.

2) 렌더러 프로세스는 HTML, Javascript 등을 처리하기 위한 프로그램 논리를 포함하여 새로 열린 웹사이트마다 새로운 렌더러 프로세스가 생성된다. 특히 샌드박스 안에서 실행되게 하여 디스크와 네트워크 입출력에 대한 접근을 제한해 보안 취약점 영향을 최소화하였다.

3) 플러그인 프로세스는 플러그인 종류마다 생성된다.


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

협력하는 프로세스의 일반적인 패러다임으로 생산자-소비자 문제가 있다.

생산자 프로세스는 정보를 생산하고 소비자 프로세스는 정보를 소비한다.

생산자-소비자 문제의 해결책: 공유 메모리를 사용하는 것 → 공유 메모리 영역에 사용 가능한 버퍼 필요

→ 데이터가 생산되는 속도와 소비되는 속도 차이에 무관, 병행으로 실행될 수 있음. but 반드시 동기화(데이터 일관성 유지) 필요

  • unbounded buffer(무한 버퍼): 버퍼 크기에 실질적 한계X. 생산자가 항상 새로운 항목 생산 가능
  • bounded buffer(유한 버퍼): 버퍼 크기 고정 가정. 소비자 반드시 대기 / 생산자는 full일 때 대기

 

유한 버퍼의 공유 메모리를 사용한 프로세스 간 통신: 

두 개의 논리 데이터 in, out을 갖는 원형 배열(circular array)의 버퍼 사용

변수 in: 버퍼 내에서 다음으로 비어 있는 위치 가리킴

out: 버퍼 내에서 첫 번째로 채워져 있는 위치 가리킴

 

생산자는 in 인덱스 위치에 항목을 삽입하고 in을 증가시킴

소비자는 out 인덱스 위치에서 항목을 제거하고 out을 증가시킴

 

버퍼 상태를 구분하는 기준:

1) in==out;일 때: empty, 비어 있는 상태

2) (in+1) % BUFFER_SIZE == out;일 때: full, 가득 차 있는 상태.

 

* 한 칸을 비워두는 이유: 빈 상태와 가득 찬 상태를 구분하기 위해 flag 변수 할당 대신 full을 표현하려는 목적.

* 동기화 메커니즘을 포함한 코드가 아님. (동기화 챕터에서 학습)


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

메시지 전달 방식:

동일한 주소 공간을 공유하지 않고도(=공유 변수 없이) 프로세스들이 통신을 하고, 동기화할 수 있도록 허용하는 기법 제공

통신하는 프로세스들이 네트워크에 의해 연결된 다른 컴퓨터들에 존재할 수 있는 분산환경에서 특히 유용하다.

 

최소 두 가지 연산 제공:

send(message) - 고정 길이 또는 가변 길이로 전송 가능

receive(message)

 

프로세스 간 통신 연결(communication link)의 논리적 구현:

직접 또는 간접 통신

동기식 또는 비동기식 통신

자동 또는 명시적 버퍼링

 

직접 통신(Direct Communication)

통신을 원하는 프로세스는 통신의 수신자, 송신자 이름 명시(대칭성)

send(P, message)

receive(Q, message)

 

특성:

통신을 원하는 각 프로세스 쌍 사이에 연결 자동 구축

연결이 정확히 두 프로세스 사이에만 연관

통신하는 프로세스의 각 쌍 사이에 정확하게 하나의 연결만 존재

 

간접 통신(Indirect Communication)

메시지들이 메일박스(mailbox) 또는 포트(port)로 송신되면 이를 통해 수신받음

메일박스: 추상적으로 프로세스들에 의해 메시지들이 넣어지고, 메시지들이 제거될 수 있는 일종의 큐와 같은 역할(객체)

각 메일박스는 고유의 id를 가지고, 다수의 메일박스를 통해 다른 프로세스와 통신할 수 있다.

두 프로세스들이 공유 메일박스를 가질 때만 프로세스가 통신할 수 있다.

새로운 메일박스 생성, 메일박스를 통한 메시지 송수신, 메일박스 삭제 연산 수행

send(A, message) - 메일박스 A로 메시지 송신

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

 

특성:

한 쌍의 프로세스들 사이의 연결은 이 프로세스들이 공유 메일박스를 가질 때만 구축된다.

연결은 두 개 이상의 프로세스들과 연관될 수 있다.

통신하고 있는 각 프로세스 사이에 다수의 서로 다른 연결이 존재할 수 있고, 각 연결은 하나의 메일박스에 대응된다.

 

여러 프로세스가 메일박스를 공유하는 경우의 문제점 해결:

어느 프로세스가 메시지를 수신할 것인지 시스템이 임의로 선택하도록 하거나, 선택 알고리즘을 정의한다.

 

동기화(Synchronization)

send와 receive 프리미티브를 구현하기 위한 설계 옵션:

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

send와 receive의 다른 조합도 가능하다.

send와 receive가 모두 봉쇄형일 때, 송신자와 수신자 간 랑데부(rendezvous)를 갖는다.

send와 receive를 사용하면 생산자-소비자 문제가 사소한 문제가 된다.

 

버퍼링(Buffering)

통신 연결 방식에 상관없이 통신 프로세스 간 교환되는 메시지는 임시 큐에 들어있다.

큐를 구현하는 방식:

1. 무용량(zero capacity): 큐의 최대 길이 0(메시지 0개) = 대기하는 메시지를 가질 수 없고, 송신자는 수신자가 메시지를 수신할 때까지 기다려야 함.

2. 유한 용량(bounded capacity): 큐가 유한한 길이 n(최대 n개의 메시지) 가짐 = 링크가 꽉차면 송신자는 큐 안에 공간이 이용 가능할 때까지 봉쇄됨.

3. 무한 용량(unbounded capacity): 큐는 잠재적으로 무한한 길이 = 송신자가 절대 봉쇄되지 않음(never wait)


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

POSIX 공유 메모리(POSIX Shared Memory)

메모리-사상 파일을 사용하여 구현됨

프로세스가 shm_open() 시스템 콜을 사용하여 공유 메모리 객체 생성:

fd = shm_open(name, O_CREAT | O_RDWR, 0666);

객체가 설저되면 ftruncate() 함수를 사용해 객체 크기를 바이트 단위로 설정:

ftruncate(fd, 4096);

mmap() 함수가 공유 메모리 객체를 포함하는 메모리-사상 파일 구축 → 공유 메모리 객체에 접근할 때 사용될 메모리-사상 파일의 포인터 반환

POSIX 공유 메모리 API를 설명하는 생산자 프로세스 / 소비자 프로세스

 

Mach 메시지 전달(Mach Message Passing)

Mach 운영체제: 마이크로커널. 대부분의 통신을 포트(port)라고 하는 메일박스로 메시지를 통해 수행.

포트: 크기가 정해져 있고 단방향. 여러 송신자가 있을 수 있지만 수신자는 오직 하나이다.

시스템 콜 = 메시지

각 태스크(task)가 Kernel과 Notify 두 개의 포트를 얻음

port_allocate(): 새 포트 작성(메일박스 생성), 메시지 큐를 위한 공간 할당

mach_msg(): 메시지를 주고 받는 표준 API. 함수의 매개변수 중 하나가 mach_send_msg 또는 mach_rcv_msg 값을 가짐

송수신 작업에 융통성이 있다. 큐가 가득 차지 않은 경우 메시지가 큐에 복사되고 전송 작업이 계속됨.

포트의 큐가 가득 찬 경우 송신자는 mach_msg()의 매개변수를 통해 옵션을 선택할 수 있다.

1. 큐에 공간이 생길 때까지 무기한 대기

2. 최대 n 밀리초 동안 대기

3. 즉시 복귀

4. 메시지를 일시적으로 캐시. 운영체제에 전달하여 보존

 

파이프(Pipes)

일반 파이프는 생산자-소비자 형태로 두 프로세스 간 통신을 허용(단방향 통신)

생산자는 파이프의 한 종단에 쓰고, 소비자는 다른 종단에서 읽는다.

 

UNIX에서 파이프 구현:

pipe(int fd[]): 파일 설명자를 통해 접근되는 파이프 생성

fd[0]: 파이프의 읽기 종단

fd[1]: 파이프의 쓰기 종단

파이프를 파일의 특수한 유형으로 취급하여 일반적인 read()와 write() 시스템 콜을 사용해 접근될 수 있게 함.

부모 프로세스가 파이프를 생성하고, 자식 프로페스를 생성하기 위하여 fork() 호출

부모 프로세스가 파이프에 쓰고, 자식 프로세스가 파이프로부터 읽는다.

부모와 자식 프로세스 모두 자신들이 사용하지 않는 파이프의 종단을 닫는다.

데이터가 도착하거나 반대쪽 파이프를 닫아야만 read() 실행이 완료됨


8. 클라이언트 서버 환경에서 통신(Communication in Client-Sever Systems)

Sockets: 통신 프로토콜 이용(네트워크를 통한 프로세스 간 통신 지원)

Remote Procedure Calls: 다른 주소 공간에서 실행 중인 프로세스가 마치 로컬에서 실행할 수 있도록 지원

Pipes: 한 프로세스의 출력을 다른 프로세스의 입력으로 직접 전달할 수 있는 유닉스 통신 메커니즘

Remote Method Invocation(Java): RPC의 객체지향 버전. 원격 객체에 대한 메소드 콜 지원

 

소켓(Socket)

통신의 endpoint를 뜻함. 두 프로세스가 네트워크상에서 통신하려면 프로세스마다 하나씩, 총 두 개의 소켓 필요.

IP 주소와 포트 번호 두 가지를 접합(Concatenation)하여 소켓을 구별

ex. 161.25.19.8:1625면 포트 번호는 1625, 호스트의 IP 주소는 161.25.19.8

서버가 지정된 포트에 클라이언트 요청 메시지가 도착하기를 기다리다가, 요청이 수신되면 서버가 클라이언트 소켓으로부터 연결 요청을 수락함으로써 연결 완성

모든 연결은 유일한 소켓 쌍으로 구성된다.

1024 미만의 모든 포트는 well-known 포트로 간주되어 표준 서비스를 구현하는 데 사용

특별한 IP 주소 127.0.0.1: loopback을 나타냄. 프로세스를 실행 중인 자기 기계(시스템)를 지칭하는 것.

 

Java가 제공하는 소켓 프로그램

연결 기반(TCP) 소켓: Socket 클래스로 구현

비연결성(UDP) 소켓: DatagramSocket 클래스 사용

MulticastSocket: DatagramSocket 클래스의 서브클래스 MulticastSocket 클래스 사용. 여러 수신자에게 데이터 송신 가능

 

TCP 소켓을 사용하는 date 서버 예제:

Date 서버

클라이언트가 이 서버로부터 현재 날짜와 시간을 알아볼 수 있다.

 

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

네트워크에 연결된 두 시스템 사이의 통신에 사용하기 위하여 프로시저 호출 기법을 추상화하는 방법으로 설계

원격 기계에서 실제로 실행되는데 마치 로컬에 있는 것처럼 사용

 

Ports: 단순히 메시지 패키지의 시작 부분에 포함되는 정수. 여러 개 가질 수 있음.

Stubs: 클라이언트 쪽에 제공하여 통신을 하는 데 필요한 세부사항을 숨겨준다.

클라이언트가 원격 프로시저를 호출하면 RPC는 대응하는 Stub을 호출하여 원격 프로시저가 필요로 하는 매개변수를 건네줌 → 스텁이 원격 서버의 Port를 찾고 매개변수를 정돈(marchall)하며, 메시지 패싱을 통해 서버에 메시지를 전송한다.

 

 

 

프로세스 간 통신 기법

반응형