Shine's dev log

IPC_2 (signals, RPCs, pipe) 본문

운영체제

IPC_2 (signals, RPCs, pipe)

dong1 2020. 4. 14. 15:29

지난번에 프로세스끼리의 통신 모델에 대하여 알아보았다.

 

그렇다면 이제 이론적인 개념에서 벗어나 실제로 어떻게 프로세스들끼리 통신을 하는지 알아보자.

 

Inter-process communication의 방법으로는

 

크게 1) signals 2)RPCs 3)pipe 이렇게 세가지를 대표적으로 생각해볼 수 있다.

 

 

 

1. signals

 

signal은 어떤 프로세스가 다른 프로세스에게 또는 운영체제가 다른 프로세스에게

 

"너 이런이런 일이 발생했어" 라고 알려주는 것이다.

 

이렇게 알려준 내용을 운영체제가 상대방에게 전달해주고,

 

signal을 받은 프로세스는 signal handler가 signal을 처리해준다.

 

예를들어 프로세스가 실행중일때 컨트롤+c 를 누르면

 

운영체제가 그 프로세스에게 SIGQUIT 이라는 signal을 날려준다.

 

그 프로세스는 SIGQUIT이라는 signal을 받고, 자신의 signal handler에 따라 처리되는 과정이 일어난다.

 

signal을 일으키는 이벤트는 크게 4가지로 정리할 수 있는데,

 

1) HW exception (e.g. 0으로 나눌때)

2) SW condition (e.g. timer)

3) 사용자 입력 (e.g. ^C, ^Z)

4) kill 과 같은 시스템콜

 

이렇게 정리할 수 있다.

 

signal handler 는 기본적으로 default로 정해져있지만, 유저가 override하여 새로 설정해줄 수도있다.

 

signal에는 어떤 사건이 발생했을때 (예측 가능한 지점에서, instruction 실행할때)

 

발생하는 synchronous signal이 있고 (e.g. illegal memory access)

 

그렇지않고 갑자기 뜬금없이 발생하는 asynchronous signal 이 있다. (e.g. kill)

 

참고로 kill은 시그널은 보내주는 시스템콜이다.

 

 

 

2. RPCs

 

signal의 경우 같은 컴퓨터에 있는 프로세스사이의 통신을 처리한다면

 

다른 컴퓨터에서 함수를 불러 처리하고 싶을 때 사용하는 것이

 

Remote procedure calls (RPCs)이다.

 

Remote procedure calls

 

위의 그림에서 알 수 있듯이 client가 특정 함수를 사용하고 싶으면,

 

그 함수에 필요한 매개변수 등을 잘 패키징해서 서버에게 보내면,

 

서버가 데이터를 가지고 결과값을 도출해낸다. 이후에 나온 결과값을 다시 client가 가져가는 식으로 활용할 수 있다.

 

이때 문제점이 하나 발생하는데, client와 서버의 컴퓨터가 데이터를 주고받는 과정에서

 

같은 형식으로 나타내지 않을 수 있다는 것이다. (e.g. big-endian & little-endian)

 

그렇기 때문에, 자신의 컴퓨터 범위를 넘어갈때는 중립적인 형태로 보내줘야한다.

 

이 중립적인 형태를 External Data Representation (XDR) 형태라고 한다.

 

위의 그림에서 RPC layer까지는 각자 컴퓨터의 local representation으로 나타내지만

 

그 아래의 network layer에서는 XDR 로 주고받아야 한다.

 

이 때 local representation을 XDR로 바꾸는 과정을 marshalling, 그 역과정을 demarshalling 이라고 한다.

 

이런 Remote Communication의 경우에는, signal을 이용한 방법에 비해 실패확률이 높다는 단점이 있다.

 

 

 

3. Pipe

 

파이프는 실제로 우리가 생각하는 그 파이프를 생각해보면 된다.

 

두 프로세스 사이에 빨대처럼 파이프를 꽂아서 데이터를 공유할 수 있게 하는 개념이다.

 

또한, 파이프는 초기 유닉스 시스템에서부터 있었던 IPC 메커니즘 중 하나이다.

 

파이프는 한쪽으로만 전송이 가능한 unidirection과 양쪽으로 전송이 가능한 bidirection으로 나뉘어진다.

 

또, bidirection이라면, 한번에 한쪽씩 전송 가능한 half-duplex와

 

동시에 양쪽으로 전송이 가능한 full-duplex로 나뉘어진다.

 

파이프의 종류로는 ordinary pipe와 named pipe가 있는데,

 

ordinary pipe는 child - parent 프로세스 사이에만 가능한 파이프이다.

 

ordinary pipe는 unidirectional 하다는 특징이 있다.

 

예를 들어 int pipefd[2] 이렇게 선언된 파이프는

 

pipfd[0]는 read만 가능하고 pipefd[1] 은 write 만 가능한 형태로 쓰인다.

 

 

위의 그림이 ordinary pipe의 개요를 나타낸 그림인데,

 

기본 검은색 화살표 외에도 분홍색 으로 부모자식간의 connection이 생기게 된다.

 

그래서 parent가 write한 데이터를 parent의 pipefd[0]에서도 read할 수 있고, child의 pipefd[0]에서도 read할 수 있다.

 

이렇게 되면, ordinary pipe의 unidirectional한 컨셉이 깨지기 때문에

 

 

이런식으로 필요에따라 한쪽을 닫아버리면 unidirectional 한 컨셉을 유지할 수 있다.

 

반면, named pipe는 child - parent 프로세스가 아니더라도 가능한 파이프이다.

 

named pipe는 bidirectional 하고,

 

심지어 프로세스가 terminate 된 이후에도 파이프는 살아있다는 특징이 있다.

 

 

오늘 내용을 정리해보면

 

1. 프로세스간 통신으로는 signal, RPCs, pipe등이 있다.

 

2. signal은 프로세스에게 직접 신호를 줘서 알려주는 것이고

 

3. RPCs는 원격 서버에 있는 함수등을 사용할 때 쓰는 것이고

 

4. pipe는 두 프로세스간 데이터 교환시 사용한다.

 

 

본 내용은 공부하며 정리한 것으로, 치명적인 오류가 있을 수 있습니다.

'운영체제' 카테고리의 다른 글

UNIX 의 파일 처리  (0) 2020.04.15
Unix 시스템 소개 및 구조  (0) 2020.04.15
IPC_1 (cooperating process model)  (0) 2020.04.12
프로세스 생성, 대체, 종료  (0) 2020.04.09
프로세스의 개념  (0) 2020.04.08