본문 바로가기
  • AI (Artificial Intelligence)
Skills/Interface

프로세스간 통신(IPC ; Inter-Process Communication)

by 로샤스 2014. 4. 2.

IPC라는게 필요한 배경??

p1, p2, p3라는 프로세스가 있습니다. p1이 작업중에 문제가 생겼는데, 만일 p2나 p3같은 다른 주소공간을 침범(write)해 버린다면?

즉, p2나 p3의 스택영역을 건드린다면 정말 큰 문제가 발생하겠지요!!

이것은 "비정상공유" 가 이뤄진 것인데, 아주 큰 문제입니다.

그래서 커널은 이것을 막기위해 Protection 을 합니다.

 

Protection ??

커널은 임의의 프로세스가 다른 프로세스의 주소공간에 접근(access)하는 것을 금지하는 것입니다.

그러고는 오직 커널만이 모든 프로세스의 주소공간에 접근할 수 있도록 합니다. 커널은 신뢰되는 것이기 때문이지요. 그래서 디바이스 드라이버를 작성하든 뭘하든 커널을 잘못 건드리면 전체 시스템이 잘못될수 있는거구요.

 그렇다면, 프로세스 사이에서 데이터 통신을 수행해야 하는 경우에는 어떻게 해야 할까요??

  

IPC (Inter-Process Communication) 란??

프로세스 사이의 데이터통신은 IPC를 통해서 합니다. IPC는 영문 약자 그대로 "프로세스 간 통신"이라는 뜻이구요, 커널은 프로세스 통신을 위해 다양한 IPC매커니즘을 제공합니다.

 프로세스는 IPC를 통하여 다른 프로세스에게 데이터를 송신하거나, 다른 프로세스로부터 데이터를 수신할 수 있습니다.

 IPC가 필요한 예로는 :

LCD에 출력할 문자 메세지를 전달하거나,

센서로부터 읽은 값을 다른 프로세스한테 전달하거나,

디스플레이에 그릴 비트맵 데이터를 전달하는 등등...

 

수도없이 많은 예가 있겠네요!

 

IPC의 종류??

IPC의 종류는 여러가지가 있겠지만, 대표적으로

 

1. 시그널 (Signal)

2. 파이프 (Pipe)

3. 메세지 큐 (Message Queue)

4. 공유 메모리 (Shared Memory)

5. 메일박스 (Mailbox)

 

등등 을 들수 있겠습니다~

 

 

1. 시그널 (Signal)

예전에 상훈이가 스터디때 강조했던 시그널은 임의의 프로세스에세 특정 이벤트가 발생했다는 사실을 알려주는 매커니즘이지요.

(예를들어, 리눅스에서 Ctrl + C 가 눌리면 SIGINT시그널이 프로세스에 전달되어 중단되는 것처럼)
이것은 이벤트 발생 -> 시그널 전달 -> 시그널 처리 의 순으로 진행됩니다.

시그널의 종류는 운영체제에서 미리 정의하며, 그러므로 운영체제에 따라서 다르겠지요.

근데 엄밀히 말해서 시그널은 신호를 발생시키는 매커니즘이고, 데이터를 전달하는 매커니즘은 아닙니다.

시그널 전달이 이뤄지는 과정은 다음과 같습니다.

일단 PCB(Process Control Block ; 리눅스에서 task_struct 같은~ )에 시그널 개수만큼 미리 확보된 시그널 벡터가 있습니다.

시그널 개수만큼 확보되어있기 때문에, 평소에는 0으로 clear되어 있다가 해당 시그널이 발생하면 그 bit만 1로 set 해주면 되는것이지요.

즉, 3번 시그널이 전달되면 3번 시그널벡터가 1로 set되는 것입니다.

시그널이 발생하면, 프로세스는 기존의 수행 흐름에서 벗어나, 해당 시그널 핸들러를 수행합니다.

시그널 핸들러는 커널이 지정해놓을 수도 있고(예를들어 프로세스 종료, 시그널 무시, 프로세스 중지, 실행 재개 등등) 사용자가 특정 기능을 수행하는 코드도 등록해 놓을 수 있습니다.

시그널 핸들러는 시그널 공간 할당 후에 함수포인터를 만들어서 시그널을 처리할 함수의 주소를 가리키도록 해놓는 방식으로 구현하게 됩니다.

시그널에 대해 더 자세히 알고싶으시면 카페에서 시그널로 검색하시면 됩니다ㅋㅋ

그렇다면 이제 데이터를 통신하는 IPC 매커니즘에 대해 알아봅시다.

 

2. 파이프(Pipe)

파이프는 프로세스 사이에 형식없는(unstructured) 데이터의 교환을 가능케 합니다. 파이프를 통해 전달되는 데이터는 단순한 바이트 스트림 형태로 전달됩니다.

파이프는 말그대로 파이프처럼 생겼다고 생각하시면 됩니다.

프로세스1 =>  파이프  =>  프로세스2     요렇게 되는것입니다.

리눅스에서 쉘명령어중에   |   <- 요것도 파이프입니다.

많이들 쓰시다시피 ls | grep ~~ 이런식으로 많이 쓰지요. 이것의 뜻은 "ls의 출력을 grep의 입력으로!" 라는 뜻이지요.

파이프의 특징은 다음과 같습니다.

- 파이프 안의 데이터는 바이트스트림(형식 없는 데이터)로 취급되기 때문에, 여러 메세지 객체가 쓰여졌을 때, 메세지의 경계를  분간할 수 없습니다.

- 또한 파이프는 FIFO(First In First Out)방식으로 데이터를 처리하므로, 메세지가 파이프에 들어온 순서대로 처리됩니다.

- 파이프는 고정된 크기(용량)을 갖습니다.

- 파이프의 데이터가 용량을 초과하면, 파이프에 데이터를 쓰는 프로세스는 "블록" 상태가 됩니다. 파이프에 쓰려고 하는데 파이프 용량이 꽉 찼으니 파이프가 데이터 쓰기 가능 상태가 되기 전까지 블록되는 것 입니다~!

 - 반대로, 파이프가 텅 비어있으면, 파이프에서 데이터를 읽는 프로세스는 "블록" 상태가 됩니다. 파이프에서 데이터 읽으려고 하는데 파이프가 비어있으니, 파이프에 데이타가 쓰여져서 그걸 읽기전까지 블록되는 것 이지요!!

 

3. 메세지큐(Message Queue)

메세지큐는 파이프와 유사하게 프로세스들 간의 데이터통신(메세지 통신)을 위한 IPC입니다.

하지만, 메세지는 structured data이기 떄문에, 경계가 구분 가능합니다. 그러므로 하나의 메세지큐 안에 여러개의 메세지를 버퍼링 할 수 있습니다!

또한 FIFO, LIFO(Last In First Out) 을 모두 지원하며, 고정된 크기를 갖습니다.

메세지큐는 다음과 같은 구조를 가지고 있습니다.

------------------------------------------------------

송신큐 => 메세지큐 => 수신큐

------------------------------------------------------

요기서 송신 프로세스가 자기 주소공간에서  메세지큐 주소공간으로 보낼 것을 복사하게 되고, 메세지큐는 자기 복사된 것을 수신 프로세스의 주소공간으로 복사하는 방식으로 동작합니다.

이렇게 되면 복사가 2번 일어나므로 overhead 이죠!

그래서 많은 양의 데이터를 전송하는 프로그램이 있다면 2번의 메모리 복사는 큰 부담입니다.

결과적으로, 많은 양의 데이터를 전달할 때에는 데이터 대신 그 데이터를 가리키고 있는 포인터만 전달하는 방법을 사용합니다.

메세지큐 사용시에 메세지 송수신을 양방향으로 이루어지게 하면 클라이언트/서버 시스템 설계에 사용할 수 있습니다.

 

4. 공유 메모리 (Shared Memory)

공유 메모리는 두 개 이상으 프로세스가 특정한 메모리 영역을 공유하는 것을 말합니다. 이 공유메모리 영역에 대한 쓰기와 읽기작업을 통해 데이터통신이 가능한 것입니다.

이 공유메모리를 사용할 때 가장 중요한것은 Race Condition이 일어나지 않도록 동기화 매커니즘을 적절히 사용하는 것입니다.

예전에 말했던 쓰레드개념도 이와 비슷하지요. 지역 변수는 각각 가지지만, 전역 변수는 여러 쓰레드(태스크)가 공유할 수 있기 때문에 공유 메모리를 사용하는 것입니다.

 

5. 메일박스 (Mailbox)

메일박스는 메세지큐와 비슷한데, 구현이 훨씬 간단하고 단순한 기능을 가집니다. 한 개의 메세지를 전달할 수 있는 IPC입니다.

 

 

 

 

 

 

출처 : http://cafe.naver.com/cmenia/3068

 

 

 

 

 

 

 

'Skills > Interface' 카테고리의 다른 글

QA Testing — What is DEV, SIT, UAT & PROD?  (0) 2020.12.21
Socket 에 대한 기본지식  (1) 2014.03.03
MAXIM 스마트 카드 I/F 원리  (0) 2014.02.26

댓글