Interview/OS

Multiprocess 간 IPC 중 Shared memory 통신

김 정출 2024. 9. 27. 18:04

Shared memory 통신

Multiprocess 간의 통신(IPC, Inter-Process Communication)은 서로 다른 프로세스가 데이터를 주고받거나 리소스를 공유하는 방법입니다. 운영체제에서 프로세스는 독립된 메모리 공간을 가지기 때문에 직접적으로 데이터를 공유할 수 없습니다. 따라서 IPC 기법을 사용하여 프로세스 간의 데이터를 전달하거나 동기화해야 합니다.

LinuxUnix에서 사용하는 다양한 IPC 방법들을 아래에 설명합니다.

3. 공유 메모리 (Shared Memory)

  • 공유 메모리는 여러 프로세스가 같은 메모리 공간을 공유하여 데이터를 주고받는 방법입니다. 가장 빠른 IPC 방법 중 하나로, 프로세스 간에 직접적인 메모리 접근을 가능하게 합니다.
  • 하지만, 동기화 문제가 발생할 수 있어, 이를 해결하기 위해 세마포어 같은 동기화 도구가 필요합니다.

공유 메모리 동작

  • shmget(): 공유 메모리 블록을 생성하거나 가져옵니다.
  • shmat(): 생성된 공유 메모리 블록을 프로세스의 주소 공간에 매핑합니다.
  • shmdt(): 매핑된 공유 메모리를 프로세스에서 분리합니다.
  • shmctl(): 공유 메모리의 제어 작업을 수행합니다 (삭제, 상태 조회 등).

이 방법은 데이터가 매우 빠르게 전달되지만, 동기화 제어가 복잡해질 수 있습니다.

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <unistd.h>

#define KEY 1234  // 공유 메모리를 식별할 키
#define SIZE 1024  // 공유 메모리 크기 (1KB)

int main() {
    int shmid;
    char *shmaddr;

    // 1. 공유 메모리 세그먼트 생성
    shmid = shmget(KEY, SIZE, IPC_CREAT | 0666);  // 0666은 읽기/쓰기 권한
    if (shmid == -1) {
        perror("shmget failed");
        return 1;
    }

    // 2. 공유 메모리를 현재 프로세스에 연결
    shmaddr = (char *)shmat(shmid, NULL, 0);  // NULL을 주면 시스템이 자동으로 주소를 할당
    if (shmaddr == (char *)-1) {
        perror("shmat failed");
        return 1;
    }

    // 3. 공유 메모리에 데이터 쓰기
    strcpy(shmaddr, "Hello from shared memory!");

    printf("Data written to shared memory: %s\n", shmaddr);

    // 4. 공유 메모리 분리
    if (shmdt(shmaddr) == -1) {
        perror("shmdt failed");
        return 1;
    }

    return 0;
}

// 다른 프로그램
int main() {
    int shmid;
    char *shmaddr;

    // 1. 공유 메모리 세그먼트 가져오기
    shmid = shmget(KEY, SIZE, 0666);  // 이미 생성된 공유 메모리 세그먼트 가져오기
    if (shmid == -1) {
        perror("shmget failed");
        return 1;
    }

    // 2. 공유 메모리를 현재 프로세스에 연결
    shmaddr = (char *)shmat(shmid, NULL, 0);  // NULL을 주면 시스템이 자동으로 주소를 할당
    if (shmaddr == (char *)-1) {
        perror("shmat failed");
        return 1;
    }

    // 3. 공유 메모리에서 데이터 읽기
    printf("Data read from shared memory: %s\n", shmaddr);

    // 4. 공유 메모리 분리
    if (shmdt(shmaddr) == -1) {
        perror("shmdt failed");
        return 1;
    }

    // 5. 공유 메모리 삭제
    if (shmctl(shmid, IPC_RMID, NULL) == -1) {
        perror("shmctl failed");
        return 1;
    }

    printf("Shared memory deleted successfully.\n");

    return 0;
}