Written by JS970
on
on
운영체제 2023-03-27 수업정리
Flow
- IPC
- IPC - Shared Memory
- IPC - Message Passing
- Examples of IPC Systems
- Communications in Client-Server Systems
IPC
IPC(Inter Process communication)
- 시스템에 속한 프로세스들은 independent일수도 있고, cooperating일수도 있다.
- Reason for Cooperating Process
- 정보의 공유
- 계산속도 향상
- 모듈화
- 편의성
- cooperating프로세스들은 서로가 서로에게 영향을 끼친다.
- IPC를 구현하는 방법으로는 아래와 같은 방법이 있다.
- Shared Memory를 사용한 IPC구현
- 하나의 시스템을 사용중이므로 이러한 구조가 가능하다.
- 공유 메모리에 Process A, Process B모두 접근 가능하다.
- 이때 Process A, Process B는 모두 User Mode이다.
- Message passing을 통한 IPC구현
- kernel영역에 속한 message queue를 사용해서 message를 전달하는 방식이다.
- Shared Memory를 사용한 IPC구현
Producer-Consumer Problem
- 상호 작용하는 프로세스의 패러다임이다.
- 정보(데이터)를 생산하는 프로세스, 정보(데이터)를 소비(사용)하는 프로세스로 나누어 생각한다.
IPC - Shared Memory
- Producer Process와 Consumer Process간의 공유 메모리를 사용하여 데이터를 전달한다.
- 이때 공유 메모리 내부에는 Buffer가 존재하는데, 이 버퍼는 unbounded혹은 bounded이다.
- unbounded-buffer : 버퍼의 크기가 무제한(현실에서는 불가능)
- bounded-buffer : 유한한 크기의 버퍼 사용
- Shared Memory방식의 IPC는 User Mode의 두 프로세스 사이에서만 일어난다.(Not the Operating Systems)
- 이러한 메커니즘의 구현에 있어 동기화 issue가 존재한다.
- producer process가 데이터 생성을 하지 않았는데 consumer process가 접근하는 경우 등
- 위 동기화 문제를 해결하더라도 producer와 consumer중 "누가 먼저 시작할 것인가?" 라는 issue가 남아있다.
- 이러한 issue는 instruction 단위 동기화를 필요로 하며, 아래는 Shared data, Producer Process, Consumer process에서 이러한 동기화 문제를 반영한 코드의 예시이다.
- Shared data
#define BUFFER_SIZE 10 typedef struct { ... } item; item buffer[BUFFER_SIZE]; // 데이터 삽입 인덱스 int in = 0; // 데이터 출력 인덱스 int out = 0;
- Producer Process
item nextProduced; while(true) { // 버퍼가 가득 차 있는 상태 -> 대기 while(((in+1) % BUFFER_SIZE) == out) ; // 버퍼가 가득 차 있지 않다면 다음 데이터 버퍼에 적재 buffer[in] = nextProduced; // 버퍼 삽입 이후 버퍼 삽입 인덱스를 증가시킨다. in = (in+1) % BUFFER_SIZE; }
- Consumer Process
item nextConsumed; while(true) { // 버퍼가 비어 있는 상태 -> 대기 while(in == out) ; // 버퍼가 비어 있지 않다면 출력 버퍼를 읽어온다. nextConsumed = buffer[out]; // 출력 이후 버퍼 출력 인덱스를 증가시킨다. out = (out+1) % BUFFER_SIZE; }
IPC - Message Passing
- Message를 주고 받는 식으로 두 프로세스 간의 공유 자원 없이 이루어진다.
- 이때 kernel이 중계자 역할을 하여 프로세스 간 메시지를 전달한다.
- 이렇듯 Message Passing을 위해서는 두 개의 method를 제공해야 한다.
- send(msg)
- receive(msg)
- 프로세스 P, 프로세스 Q간의 Message Passing 방식의 통신을 위해서는
- P와 Q간의 communication link를 활성화 해야 한다.(논리적 통로)
- 논리적 통로가 제공하는 send(), receive()를 이용해 논리 통로를 이용한다.
- Message Passing의 Implementation Issue로는 아래와 같은 것들이 있다. 전부 구현 단계에서 고민할 문제이다(Implementation Issues).
- communication link는 어떻게 개설되는가?
- 두 개 이상의 프로세스에 대해서 link의 활성화가 가능한가?
- 각 쌍의 communicating processes애 대하여 얼마나 많은 communication link의 개설이 허용되는가?
- communication link의 capacity는 어떻게 되는가?
- 전달되는 message의 크기는 고정 크기인가 가변 크기인가?
- communication link를 통한 message passing은 단방향인가 양방향인가?
Direct Communication
- Direct Communication에서는 Producer Process와 Consumer Process가 서로를 직접 호출(명시적 호출) 하여 message를 주고받는다.
- send(P, message) - send a message to process P
- receive(Q, message) - receive a message from process Q
- 위와 같이 send, receive의 호출에 있어 explicit 하게 동작한다.
Indirect Communication
- Indirect Communication 에서는 mailbox를 이용한다. 이는 Port개념과 유사하다.
- 각각의 mailbox는 unique id를 가진다.
- 프로세스들은 오직 서로가 mailbox를 공유할 때만 통신 가능하다.(같은 Port에서 통신 가능하다)
- communication link역시 각 프로세스가 공통의 mailbox를 공유할 때만 개설 가능하다.
- communication link는 여러 프로세스 간에 참조 가능하다.
- 각각의 프로세스 쌍들은 수 개의 communication link를 공유한다.
- 이때, link는 단/양방향 모두 될 수 있다.
- Indirect Communication을 지원하기 위해서는 아래와 같은 operation들을 지원해야 한다.
- create a new mailbox
- send, receive
- destroy mailbox
- Indirect Communication방식으로 Message Passing을 구현할 때, 아래와 같은 issue가 발생한다.
- P1, P2, P3가 mailbox M을 공유한다.
- P1은 producer process, P2, P3는 consumer process이다.
- 이때 P2, P3중 누가 message를 수신해야 하는가?
- 위 issue의 해결 방법으로 아래와 같은 해결책이 있다. 하지만 기본적으로, 이러한 issue는 모두 구현에 따른다(Implementation Issues)
- 최대 두 개의 프로세스 간에만 communication link가 개설되도록 제한한다.
- receive operation을 두 프로세스가 동시에 수행할 수 없도록 제한한다.
- 임의적으로(arbitrarily) 선택되는 것을 허용한다.
Synchronization
- Message Passing 방식은 Blocking방식 또는 Non-Blocking방식으로 동작한다.
- Blocking - Considered synchronous
- blocking send는 message가 도착할 때까지 sender block을 가지고 있는다.
- blocking receive는 message가 전송 가능할 때까지 receiver block을 가지고 있는다.
- 기본적으로 non-blocking방식보다 overhead가 클 수밖에 없다. 하지만 message를 주고(sned) 받는(receive)과정에서의 동기화 문제에 대해 자유롭다.
- Non-Blocking - Considered asynchronous
- non-blocking send는 그냥 계속해서 message를 send한다.
- non-blocking receive는 vaild message와 null을 구분하지 않고 계속해서 receive한다.
- send, receive모두 blocking방식일 경우 rendezvous(랑데뷰)라고 한다.
- Blocking, Non-Blocking방식 모두 각각의 장점이 있으며, application에 따라 알맞은 방식으로 구현하면 된다.
Buffering
- Communication Link의 Message Queue는 다음 세 가지 중 하나의 버퍼링 방식으로 message를 처리한다.
- Zero capacity - 0 messages
- sender 는 receiver를 항상 기다려야 한다(rendezvous)
- Bounded capacity - n개의 유한한 크기의 메시지를 들고 있을 수 있다.(일반적인 경우)
- message queue가 full이라면 sender는 무조건 대기해야 한다.
- Unbounded capacity - infinite length
- 엄밀하게는 현실에서 불가능하다. 하지만 충분한 양의 메시지를 저장 가능하다면, 이 방식으로 분류한다.
- sender는 절대 기다리지 않는다.
- Zero capacity - 0 messages
Examples of IPC Systems
- Windows의 advanced local procedure call(LPC)의 동작에 관해서 살펴보자
- 클라이언트가 connection port를 통해 server로 connection 요청을 한다.
- Server는 두 개의 Private Communication Port를 생성하고, 그 중 하나에 대한 제어권을 client에게 양도한다.
- Client와 Server는 각자의 port를 사용하여 Shared Section Object에 접근 가능하다.(공유 버퍼)
Communications in Client-Server Systems
Sockets
- 네트워크 통신에서의 endpoint
- host X : 146.855.5.20:1625 <-> web server : 161.25.19.8:80
- 포트(1625, 80)를 이용해 Communication Establishment가 가능하다.
- 여기서 port number는 mailbox의 unique id와 대응된다.
- Communication Establishment되었으므로 socket통신이 일어난다.
- 포트(1625, 80)를 이용해 Communication Establishment가 가능하다.
Remote Procedure Call
- 네트워크 시스템에서 떨어져 있는 프로세스를 호출하는 과정은 아래와 같다.
- Client에서는 Stub Code를 사용하여 함수 호출에 필요한 값들을(인자 값, 함수 명 등) marshall한다.
- marshalling이란 표현 방식을 전송에 적합한 방식으로 변환하는 과정이다.
- Server의 Stub Code는 메시지를 전달받고, unmarshall한다. 그리고 server에서 전달받은 값들을 사용하여 프로세스를 호출한다.
- Client에서는 Stub Code를 사용하여 함수 호출에 필요한 값들을(인자 값, 함수 명 등) marshall한다.
- RPC의 사용을 통해 원격에 존재한 client - server에서 IPC가 가능해 진다.
Pipes
- 마치 파이프처럼 두 프로세스 간 통신을 수행한다.
- P1의 결과를 P2가 (pipe를 통해)전달받아 사용한다.
- Pipe구현 시 고려할 점
- Unidirectional or Bidirectional?
- Half duplex or Full duplex?
- Relationship(부모 프로세스 - 자식 프로세스 등)
- Environment(네트워크 환경에서의 구현인지, 아니면 같은 시스템 내의 구현인지)
- Pipe의 두 종류
- Ordinary Pipes
- 파이프를 생성한 프로세스 이외에서는 해당 파이프에 접근 불가능하다.
- 보통은 부모 프로세스가 파이프를 생성해서 자식 프로세스와의 통신에 사용한다.
- 통신에 참여하는 두 프로세스가 producer-consumer관계이다.(unidirectional)
- producer는 파이프의 한쪽 구멍을 통해 write한다.
- consumer는 파이프의 나머지 한쪽 구멍을 통해 read한다.
- 파이프를 사용한 통신이 종료되면 ordinary pipe는 사라진다.
- Named Pipes
- 부모-자식 프로세스 관계가 아니더라도 접근 가능하다.
- 양방향 구현이 가능하다(bidirectional).
- 일반적으로 유닉스 또는 윈도우 시스템에서 제공되는 형태이다.
- Ordinary Pipes
- Pipe와 Message Passing의 차이점
- Message Passing은 Mailbox를 통해 서로 다른 타입의 값에 대해서도 전달이 가능하다.
- 서로 다른 타입의 message를 linked list형태로 message queue에 저장한다.
- 즉, 서로 다른 자료구조에 대해 처리가 가능하다.
- Pipe는 기본적으로 Bytestream(혹은 bitstream)단위로 전달되기 때문에 타입에 대한 정의 자체가 없다. 따라서 서로 다른 타입에 대해서는 처리할 수 없다.
- Message Passing은 Mailbox를 통해 서로 다른 타입의 값에 대해서도 전달이 가능하다.