Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

공유 메모리(Shared Memory)를 활용한 프로세스 간 통신(IPC) 완벽 가이드


공유 메모리란 무엇인가?

공유 메모리(Shared Memory)는 두 개 이상의 프로세스가 함께 접근하여 사용하는 메모리 공간을 의미합니다. 그렇다면 왜 굳이 메모리를 공유하거나 별도의 통신 수단이 필요할까요?

각 프로세스는 독립적인 주소 공간(address space)을 가지고 있기 때문입니다. 한 프로세스가 자신의 주소 공간에 있는 정보를 다른 프로세스에 전달하려면 반드시 IPC(Inter-Process Communication, 프로세스 간 통신) 기법을 사용해야만 합니다. IPC는 부모-자식 관계처럼 서로 관련 있는 프로세스 사이에서도, 전혀 관련 없는 프로세스 사이에서도 이루어질 수 있다는 점을 이미 알고 있을 것입니다.

일반적으로 서로 연관된 프로세스 간 통신은 파이프(Pipe)나 네임드 파이프(Named Pipe)를 통해 수행됩니다. 반면 서로 관련 없는 프로세스(예: 한 터미널에서 실행되는 프로세스와 다른 터미널에서 실행되는 프로세스) 간 통신은 네임드 파이프뿐 아니라 공유 메모리(Shared Memory)나 메시지 큐(Message Queue) 같은 대표적인 IPC 기법으로 처리할 수 있습니다.

앞서 파이프와 네임드 파이프 IPC 기법을 살펴보았으니, 이제 남은 IPC 기법들인 공유 메모리, 메시지 큐, 세마포어(Semaphore), 시그널(Signal), 메모리 매핑(Memory Mapping)에 대해 알아볼 차례입니다.

공유 메모리(Shared Memory)를 활용한 프로세스 간 통신(IPC) 완벽 가이드

공유 메모리 사용을 위한 필수 시스템 콜

두 개 이상의 프로세스가 통신하기 위해 공유 메모리를 사용한다는 것은 알고 있습니다. 그렇다면 공유 메모리를 실제로 사용하기 전에 어떤 시스템 콜(system call)을 거쳐야 하는지 단계별로 확인해 보겠습니다.

  • 공유 메모리 세그먼트를 새로 생성하거나 이미 생성된 세그먼트를 사용 — shmget()

  • 프로세스를 해당 공유 메모리 세그먼트에 연결(attach) — shmat()

  • 연결되어 있던 공유 메모리 세그먼트로부터 프로세스를 분리(detach) — shmdt()

  • 공유 메모리 세그먼트에 대한 제어 작업 수행 — shmctl()

여기서는 두 개의 프로세스를 만들어 보겠습니다. 하나는 데이터를 쓰는(writer) 역할을 하고, 다른 하나는 데이터를 읽는(reader) 역할을 합니다. 공유 메모리를 이용해 쓰기 프로세스와 읽기 프로세스가 각각 어떻게 동작하는지 예제 코드를 통해 자세히 살펴보겠습니다.

쓰기 프로세스 예제 코드

#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
using namespace std;
main() {
    key_t my_key = ftok("shmfile",65); // ftok 함수는 고유한 키를 생성하는 데 사용됨
    int shmid = shmget(my_key,1024,0666|IPC_CREAT); // shmget은 식별자를 shmid에 반환
    char *str = (char*) shmat(shmid,(void*)0,0); // shmat으로 공유 메모리에 연결
    cout<<"Write Data : ";
    fgets(str, 50, stdin);
    printf("Data written in memory: %s\n",str);
    // 공유 메모리에서 분리(detach)
    shmdt(str);
}

읽기 프로세스 예제 코드

#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
using namespace std;
main() {
    key_t my_key = ftok("shmfile",65); // ftok 함수는 고유한 키를 생성하는 데 사용됨
    int shmid = shmget(my_key,1024,0666|IPC_CREAT); // shmget은 식별자를 shmid에 반환
    char *str = (char*) shmat(shmid,(void*)0,0); // shmat으로 공유 메모리에 연결
    printf("Data read from memory: %s\n",str);
    shmdt(str);
    shmctl(shmid,IPC_RMID,NULL); // 공유 메모리 삭제
}

실행 결과

공유 메모리(Shared Memory)를 활용한 프로세스 간 통신(IPC) 완벽 가이드