OS 공부

OS 공부 - 프로세스간 통신, IPC, shared memory, Message-Passing

휘로그 2024. 10. 10. 21:41
728x90
반응형

프로세스 독립적(independent)이거나 동시실행(cooperating)되거나,
독립적이면 혼자 잘 실행되고 자기들끼리 서로 영향 안 미치고 잘 공존한다.

 

독립적인 프로세스:
공유하는 데이터도 없고, 서로 메시지 주고받을 일도 없다.

 

cooperating 프로세스:
영향을 주거나 받거나 함. 데이터 , 메시지를 주고받을때 생기는 메시지 어떻게 해결할 거냐?? -> IPC
다른 프로세스들에게 영향을 줄 수 있음
다른 프로세스들과 데이터를 공유하는 프로세스들은 상호협력적인 프로세스들임

 

IPC
Inter - Process Communication
프로세스들은 프로세스들끼리 독립적이거나 또는 상호협력적으로 동시에 실행됨
데이터를 주거나 받거나 통신을 어떻게 하는지??
cooperating(상호협력적인) 프로세스들은 IPC 메카니즘필요함
데이터 공유를 허용함
다른 프로세스들로부터 데이터를 보내거나 데이터를 받을 수 있음

 

데이터 공유를 허용함
IPC 두가지 모델
shared memory : 공유 메모리를 통해 데이터 주고받음
message passing : 메시지 주고받기

 

공유 메모리(shared memory) 왼쪽: shared memory에서 아빠가 용돈 shared memory에 놓으면 자식이 통해서 서로 주고 받음
메시지 송수신(message passing) 오른쪽: os한테 맡김, 아빠가 은행에 입금하면 은행이 알아서 아들계좌에 쏴줌
메시지 큐를통해 메시지 패싱을 한다.

 

 

Producer-Consumer Problem
생산자, 소비자 문제: cooperating process 기본적인 문제
프로듀서(생산자) 정보를 생산하고, 컨슈머(소비자)는 정보를 소비한다.
예) 컴파일러가 assembly 만들면 assembler가 받아서 기계어 생산
브라우저가 리퀘스트하면 웹서버가 html파일 전송함

 

shared-memory
유튜브로치면 소비자한테 계속 영상을 보내준다. 받은 소비자는 디스플레이에 영상을 보여준다. P , Q 는 컨텍스트 스위치를 하면서 자기할일을한다. concurrently하게 실행됨
버퍼를 사용하자.
producer는 버퍼에 전송하고싶은걸 채우고 consumer 는 버퍼에서 가져간다.
P는 자꾸채우고 Q는 소비해 나감
버퍼가 가득차면 어떡하냐?? -> producer가 wait해야됨
버퍼가 비어있으면? -> consumer wait해야됨
이 버퍼를 shared-memory로 만들자 -> producer와 consumer가 공유하는 메모리
P가 fork를해서 Q가 생겼다. 서로 접근해서는 안됨 공유영역필요! OS가 해준다.

 

shared buffer
간단한 produce-consumer 모델:
in과 out을 0으로 두고 뭔가 들어오면 in 증가시킴 소비할때는 consumer가 out 증가시키고 소비

%define BUFFER_SIZE 10

typedef struct {
  . . .
} item;

item buffer[BUFFER_SIZE];
int in = 0;
int out = 0;

produce코드

item next_produce; // 아이템하나 생성

while(true) {
  while(((in + 1) % BUFFER_SIZE == out) {
  // in%bufferSize가 아웃일때까지 기다려야함 in증가하면서
    ; /* do nothing */ // 아무것도 안하면서
  }
  // 아웃이아니면
  // in 증가시키면서 in에다가 아이템 넣음
  buffer[in] = next_produced;
  in = (in + 1) % BUFFER_SIZE; 
}

 

왼쪽에 in out더 오른쪽에 있으면 넣는다. in보다 1증가시킨게 out 이면 기다림
next_produced 변수에 정보를 동적 생성 수행
반복문을 통하여 버퍼가 빌때까지 대기
buffer[in] 위치에 정보 저장
in 인덱스의 자리 이동 수행

 

consumer 코드

item next_consumed:

while (true){
  while (in == out)
    ; /* do nothing */
    
  next_consumed = buffer[out];
  out = (out + 1) % BUFFER_SIZE;
  
  /* consume the item in next_consumed */

 

in과 out 이 같으면 아무것도 없단 얘기, 같지않으면 소비할게 생겼단얘기 , 버퍼에있는 거 가져옴, 그리고 디스플레이같은 화면에 영상 뿌려주고, 아웃증가시킴 또 소비하고 소비하고 대기하고..
소비자 프로세스는 정보가 생산될때까지 반복문을 통하여 대기
next_consumed 변수에 정보를 가져와서 저장
out 인덱스의 자리 이동 수행
그 이후 문장은 item 정보를 소비함

 

서로 다른 프로세스 concurruntly하게 실행되고 버퍼를 통해서 동기화가 잘 이루어진다. 프로듀서 컨슈어 문제를 shared memory로 해결하는 기본개념.

 

shared-memory 방식의 문제
메모리 영역을 공유하게 되면 이 메모리영역을 명시적으로 쓰고 엑세스하는 것을
애플리케이션 프로그램들이 다 해줘야함
P가 여러개고 Q가 여러개고 하면 복잡하고 문제생길 수 있음

 

Message-Passing
O/S 가 cooperating processes들에게 API 제공
커뮤니케이션할 때 이 메시지 패싱을 굉장히 쉽게 할 수 있도록 도와줘라
근본개념은 shared memory인데 그건 os가 알아서하고 그냥 메시지만 던질 것

 

send(message)
receive(message)

 

file, in, out 없이 send만 씀 in이고 out이고 os 가 해줌

while(true) {
  /* produce an item in next_produced */
  send(next_produced);
}
while(true) {
  /* produce an item in next_produced */
  receive(next_produced);
}

 

couuunication Links
P와 Q 를 다이렉트로 잇는 link
send, receive 두개의 방식만 있으면 됨

 

직접적(direct)으로 보낼거냐 간접적(indirect)으로보낼거냐
동기화synchronous 할거냐 비동기화asynchronous하게 할거냐
자동적(automatic)으로 보낼거냐 명시적(explicit)으로 버퍼링해서 보낼 거냐

 

direct communication
각 프로세스가 커뮤니케이션하고자하는 상대방을 안다.
recipient , sender 에게 명시적으로 이름을 준다
send(P, message) 메시지를 프로세스 P에게 준다.
receive(Q, message) 메시지를 프로세스 Q에게 받는다.

 

통신 Link가 자동적으로 생긴다.
P와 Q사이에 한개밖에 있을 수 없다. 명시적으로 두개 프로세스만 연관됨
exactly one link만 성립한다.

 

indirect communication
P와 Q사이에 매게체가 필요
용돈함에 집어넣으면 아들이 가져가는 구조
메시지를 메일박스 (or 포트)에 보내고 받아간다.
이 오프젝트는 send는 메시지를 보내는 저장소(placed), recieve는 message를 받는 저장소(removed)
send(A, message) 메일박스 A에 메시지를 보낸다. 특정하지는 않는다.
receive(A, message) 메일박스 A에서 소비자는 가져감

 

두개의 프로세스가 메일박스(포트)를 공유할 때 페어(링크)가 생성된다.
이 링크는 여러개의 프로세스가 연관associate있을 수 있다.
(메일박스에 아빠, 엄마, 할머니 용돈 넣을 수 있고 아들, 딸, 손자, 손녀가 받을 수 있다.)
여러개의 링크가 존재할 수도 있다. 포트 여러개 있을 수있다. (아빠만 넣는 함, 엄마만 넣는함, 아들만 받는함, 두 군데서 받는 딸 등등, 복잡할 수 있다.)

 

OS는 새로운 mailbox를 제공해준다.
이 mailbox에다가 send, receive 할 수 있게 해준다.
필요없으면 mailbox 지운다.

 

blocking, non-blocking(synchronous, asynchronous)
Blocking send: 송신자는 메지지가 수신될때까지 대기
메일박스가 1GB 인데 영화가 2GB이면 못넣는다. Q가 소비해줄 때까지 wait해야됨
Non-blocking send: 송신자는 메시지를 송신하고 다른일을 수행
영화 send만 해놓고 지는 다른 일 하고 OS보고 알아서해줘라, send하고 계속 continue
Bolcking receive: 수신자는 메지지가 수신 가능 할때까지 대기
1GB먼저 들어오고 소비하고 2GB들어 올때까지 기다린다.
Non-blocking recive: 수신자는 유요한 메지지이거나 널 메시지를 수신함
리시브가 메시지 있으면 받거나 없으면 null 리턴하거나
synchronous: 예를들어 전송해놓고, 딴일안하고 다 보내지면 다른일 함, 동기적

 

Non-blocking send같은거하면 다 보냈는지 확인할 수 가 없음 - 비동기적
Blocking send 하면 다 받을때가지 기다려야하니까 느림, produce, consumer둘다 효율적으로 일 할 수 있음
=> synchronous가 필요하면 Blocking send 하면되고 실패하면 다시하면되지,, 하면 asynchronous

반응형