컴퓨터 프로세스간 통신(IPC) | Inter-Process Communication
운영체제 상에서 실행 중인 프로세스 간에 정보를 주고받는 것을 Inter Process Communication(IPC)라고 한다. 프로세스는 자신에게 할당된 메모리 내의 정보만 접근할 수 있고, 이를 벗어나서 접근할 경우, C언어를 배우는 사람이라면 누구나 한 번쯤은 봤을 Segmentation Fault 등의 오류가 발생하게 된다. 이는 안전성을 위해 운영체제에서 자기 프로세스의 메모리만 접근하도록 강제하고 있다는 것이다.
따라서 한 프로그램에서 병렬성을 키우면서 공유되는 데이터를 사용하기 위해 *메모리 공간을 공유하는 스레드를 이용하는 경우가 많다 (물론 스레드를 쓰는 이유는 이것 말고도 매우 다양하다). 하지만 이것은 하나의 프로그램에서만 의미가 있는 것이고, 서로 다른 프로그램(즉, 서로 다른 프로세스)의 데이터를 공유하려면 결국 다른 프로세스의 메모리를 접근할 필요가 발생한다. 따라서 이 때는 IPC라는 것을 사용하게 된다.
다른 것도 있다. 바로 LPC(Local Inter-Process Communication, 로컬 컴퓨터 프로세스간 통신)라는 게 있는데 프로세스가 다른 프로세스와 정보를 주고 받을 때 빠른 속도로 데이터를 교환하기 위해 사용한다. 다만 이건 커널에서만 쓸 수 있으며 일반 프로그램은 LPC를 사용할 수 없다. | 출처 : 나무위키
위의 설명에도 잘 나와 있지만 프로세스간의 커뮤니케이션을 할 수 있는 직접적인 방법은 없습니다. 이는 당연한것인데 프로세스들이 서로의 공간에 접근이 가능하다면 각각의 데이터 혹은 코드에 접근이 가능하다는 말이며, 이는 매우 위험하기 때문입니다.
이렇게 원칙적으로 금지가 되어 있는데도 불구하고 필요한 이유는 무엇일까? C언어 시스템 콜을 사용하여 예를 들어보면 하나의 CPU에 다수의 코어가 들어가는것을 당연하게 생각하는 요즘에 fork()
를 사용하여 부모, 자식 프로세스를 만들어 각 프로세스를 각 코어에 동시 실행이 가능하게하여 빠른 실행을 하기 위함 즉, 병렬 처리를 하여 빠른 프로그램의 실행이 가능하도록 하기 위함입니다. 뿐만 아니라 다양한 이유로 프로세스간의 커뮤니케이션이 필요한데 직접적인 방법은 없고, 어떻게 할 수 있을까?
가장 쉽게 생각할 수 있는 방법은 저장매체를 사용하는 것입니다. 해당 방법도 일종의 IPC 기법인데, 각각 프로세스의 데이터를 저장매체에 원하는 방법으로 저장하고 그것을 또 다른 프로세스에서 가져와 사용하는 방법을 생각할 수 있습니다.
쉽게 사용할 수 있겠지만 효율적인 방법은 아닙니다. 앞의 배웠던 내용을 생각해보면 프로세스에서 저장매체에 접근하기 위해서 시스템 콜을 호출하고.. 인터럽트를 호출하고.. 사용자 모드에서 커널 모드로 변경하고.. 등등 잠깐만 생각하더라도 효율적인 방법은 아닙니다.
먼저 프로세스의 공간에 대해서 아주 간단하게 얘기하자면 하나의 프로세스는 0Gb부터 4Gb까지 사용할 수 있는데(물론 실제 물리 램에서 사용하는 공간이 4Gb는 아니다.) 0Gb ~ 3Gb까지는 실제 프로그램이 사용하는 공간이며 3Gb ~ 4Gb는 운영체제의 코드가 들어가는 공간입니다. 쉽게 0 ~ 3Gb는 사용자 공간, 3 ~ 4Gb는 커널 공간으로 생각하면 됩니다. 당연히 사용자 공간은 커널 공간에 접근할 수 없습니다.
여기서 중요한 점은 실제 프로그램의 코드가 사용하는 공간인 사용자 공간은 당연히 프로세스마다 있어야 하지만 운영체제의 코드가 사용하는 커널 공간은 중복해서 존재할 이유가 없습니다. 당연히 운영체제에서 사용하는 코드는 정해져 있는데 프로세스마다 해당 중복 코드를 사용할 이유가 없기 때문입니다. 다시 말해 사용자 공간은 각각 존재하지만 커널 공간은 하나의 공간을 공유합니다. 즉, 각각의 프로세스들의 커널 공간이 공유가 가능하는 말이 됩니다.
그리고 위의 내용을 토대로 커널 공간의 공유로 사용할 수 있는 IPC 기법들을 간단하게 보겠습니다.
C언어의 fork()
를 사용하여 자식 프로세스를 만들었을 때의 부모와 자식간의 통신으로 기본적으로 단방향 통신의 특징이 있습니다.
FIFO 방식의 데이터 전송으로 동일한 key 값을 이용하여 A 프로세스의 데이터를 B 프로세스가 받을 수 있습니다. 반대로 B 프로세스에서도 A 프로세서로 데이터를 보낼 수 있습니다. (양방향)
앞서 얘기한 커널 공간에 메모리 공간을 만들어 해당 공간을 마치 변수처럼 사용하는 방법입니다.
공유 메모리 key를 사용하여 여러 프로세스 접근이 가능합니다.
그리고 IPC기법이긴 하지만 이외에도 많이 사용하는 두 가지 기술
유닉스에서 30년 이상 사용된 전통적인 기법으로 커널 또는 프로세스에서 다른 프로세스에 어떠한 이벤트가 발생되었는지 알려주는 기법입니다.
주요 시그널, 기본 동작으로 SIGKILL: 프로세스 죽이기
, SIGSTP: 프로세스 멈추기
, SIGCONT: 멈춘 프로세스 실행하기
등 64개의 명령어들이 있습니다.
소켓은 네트워크 통신을 위한 기술이며 기본적으로 클라이언트와 서버등 두 개의 다른 컴퓨터간의 네트워크 기반 통신을 위한 기술입니다. 그리고 해당 원리로 하나의 컴퓨터 안에서 두 개의 프로세스간에 통신 기법으로 사용는것도 가능합니다.