Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>
  • 너무 오래된 문서다 수정을 해야 할 것 같다. - 2010/1/29 하나하나의 프로그램은 그자체를 객체라고 할수 있다. 그런 의미에서 보자면, Unix 시스템은 수많은 객체가 모여서 운영되는 시스템이라고 말할수 있을 것이다. 개개의 인간이 객체로 참여하고 있는 인간사회에서 그 사회를 유지하기 위해서 가장 필수적인게 바로 "사람과 사람사이의 통신"이다. 인간이 다른 동물들과 달리 유기적이고 체계적인 지금의 사회를 유지할수 있는건 "통신"에 힘입은 바가 크다고 하겠다.

    Unix 시스템도 마찬가지이다. 수많은 객체로 이루어진 Unix 시스템이 원할히 작동 하기 위해서는 각 객체간의 원할한 "통신"이 필수적이다. 어떤객체(이하 프로세스) 가 파일을 열기 위해서는 일련의 작업을 위해서 커널과 통신을 해야할것이다. 또한 특정 프로세스가 가지는 데이타를 다른 프로세스에게 넘겨서 이를 처리하도록 하는 작업도 필요할것이며, 동일한 데이타를 몇개의 다른 프로세스가 접근해야될 필요가 있을것이다.
    이러한 데이타 통신을 위해서 Unix 에서는 IPC 라는 내부 프로세스간 통신을 위한 도구를 존재한다. (외부 프로세스를 위한 통신을 위해서는 소켓을 주로 사용한다)
    IPC 에서 대표적으로 제공하는 설비의 형태는 Pipe, FIFO, message queue, semaphore, shared memory, 그리고 파일기반소켓(AF_UNIX) 등이 있다. 이들 IPC 설비는 아직까지 표준화되지 않은 측면이 있어서, 어떤 UNIX 시스템에서는 지원하지만 다른 UNIX 시스템에서는 지원하지 않는 것들이 많으며, 모든 시스템에 공통적으로 지원하는것은 Pipe 정도가 유일하다. 이번문서에서는 혼동을 막기 위해서 Linux 시스템을 기준으로 IPC 에 대해서 설명하도록 하겠다.

    pipe
    pipe 는 모든 유닉스에서 지원되는 거의 유일한 ipc 설비이며, 가장 표준에 가까우며, 또한 가장오래된 ipc 의 형태이다.
    유닉스 사용자는 거의 매일 pipe 를 사용한다고 볼수 있다. 아래를 보라.
    파이프의 실제 사용예를 들어보았다.
    [yundream@localhost test]# ls -al | less
    ....
    [yundream@localhost test]# ps -aux | grep httpd | grep -v grep
    ...
    [yundream@localhost test]# echo "hello world" | wc -w
    ..
    
    위의 예제를 보면 알겠지만 pipe 는 한 프로세스의 데이타를 다른 프로세스에게 넘기기 위한 목적으로 사용된다. 데이타는 한쪽방향으로만 흐를수 있으며(읽거나 쓸수만 있고, 동시에 읽고 쓰기를 할수는 없다.- Read only or Write only), 동일한 부모를(PPID가 같은) 가지는 process 사이에서만 사용이가능 하다는 특징이 있다. 이러한 특징은 단점으로 작용하는데, 이러한 단점을 해결한 pipe 와 유사한 다른 설비에 대해서도 이문서 후반에 다루도록 하겠다. 그리 복잡하지 않은 시스템에서 한방향으로 데이타를 보내고자 할때 간단하게 사용할수 있는 설비이다.

    message queue(메시지 큐) queue 는 자료구조의 한종류인데, 먼저 들어온자료가 먼저 나가는 구조로써, stack 과는 반대되는 개념이다. 은행 창구 혹은, 극장 티켓 끊기를 생각하면 이해가 쉬울것이다.
    메시지 큐 는 위에서 설명한것 과 같은일을 하는데, 일반적으로 프로그래밍에서 쓰이는 큐가 내부 자료구조를 위한것이라고 하면, 메시지 큐는 서로 다른 프로세스들간의 자료 전달을 위한 것이 다른점이다.
    또하나 메시지 큐는 프로그램의 메모리에서 관리하는게 아닌, 커널메모리에서 관리를 하므로, 프로그램이 종료한다고 해서 메시지 큐가 사라지는건 아니다. 그러므로 관리자는 종종 현재의 메시지큐 상태를 확인해줄 필요가 있는데, 이럴경우 ipcs 명령을 사용하게 된다.
    [yundream@localhost test]# ipcs -q
    
    ------ Message Queues --------
    key        msqid      owner      perms      used-bytes   messages
    0x00003039 0          root       600        8            1
    0x0000303b 32769      root       600        8            1
    
    ipcs 를 사용하면 현재 ipc 자원상태를 살펴볼수 있으며, ipcrm 을 이용해서 필요없는 ipc 자원을 정리할수도 있다. 이에 대한 자세한 내용은 man 페이지를 참고하기 바란다. 위의 에제를 보면 msqid 라는 정수형의 숫자가 보일것이다. 우리는 이 msqid 를 이용해서 메시지 큐 에 접근해서 메시지 큐에 데이타를 보내거나, 메시지큐에 들어 있는 메시지를 읽어올수가 있다.

    FIFO
    FIFO 는 위에서 설명한 pipe 와 매우 유사하다. FIFO 는 위에서 설명한 pipe 의 단점중 같은 PPID(같은 부모프로세스)를 가지는 프로세스들 사이에서만 통신이 가능하다는 단점을 해결한, pipe 의 확장버젼이라고 할수 있을것이다. FIFO는 부모프로세스와 무관하게 전혀다른 모든 프로세스들 사이에서 통신이 가능한데, 그이유는 프로세스 통신을 위해서, 이름이 있는 파일을 사용하기 때문이다.
    FIFO 의 생성은 mkfifo(1) 을 통해서 이루어지는데, mkfifo 를 성공하면 명명된 파일이 생성된다. 이 파일의 정보를 보면 다음과 같다.
    -rw-r--r-- 1 root root 0 1월 12 22:31 lock drwx------ 2 root root 4096 1월 11 02:48 mcop-root prw------- 1 root root 0 1월 22 00:32 myfifo
    제일 마지막 줄에 보면 myfifo 란 파일이 있을것이다. 가장앞부분을 보면 "p" 라고 되어 있는데, FIFO 설비로 만들어진 파일이란걸 알려준다. FIFO도 pipe 의 또다른 단점인 읽기/쓰기 가 동시에 가능하진 않으며, read-only, write-only 만 가능하다. 하지만 통신선로가 파일로 존재하기 때문에, 하나를 읽기전용으로 열고 또 다른 하나를 쓰기 전용으로 열어서, 이러한 read/write 문제를 해결할수는 있다. 호스트영역의 서버 클라이언트간 전이중 통신을 위해서는 결국 2개의 FIFO 파일이 필요하게 된다.(이러한 점은 PIPE를 통한 부모/자식 프로세스간 통신도 마찬가지다.)

    이상 Unix 에서 대표적으로 사용되는 IPC 설비들에 대해서 알아보았다. 이문서에서 모든 IPC 설비를 다룬건 아닌데, 그중 Semaphore 가 빠져 있다. 이유는 비록 Semaphore 가 IPC 설비로 분류가 되긴 하지만, 메시지를 직접전달하는 다른 설비들과는 좀 무관하기 때문에 제외를 시켰다. Semaphore 에 대해서는 다른 문서를 통해서 설명을 하도록 하겠다. 여기에 등장했던 IPC 에 대한 코드 차원에서의 설명은 차근차근 해나갈 것이니 기대를 해주길(--;) 간절히 바라는 바이다.