공유 메모리

Brie·2023년 12월 1일
0

운영체제(OS)

목록 보기
6/6

개요

공유 메모리는 Linux/UNIX 운영체제에서 프로세스 간 데이터 공유를 위한 메커니즘 중 하나이다.
공유 메모리를 사용하는 주된 사용 용도는 다음과 같다.

  1. 데이터 공유 및 프로세스 간 통신:
    • 여러 프로세스 간에 데이터를 공유하기 위해 사용된다. 예를 들어, 한 프로세스가 생성한 데이터를 다른 프로세스가 손쉽게 읽거나 수정할 수 있다. 이는 프로세스 간에 데이터를 교환하고 동기화 할 수 있는 IPC 메커니즘의 한 종류라고 볼 수 있다.
  2. 성능 향상:
    • 여러 프로세스가 동시에 메모리에 접근할 수 있으므로, 특히 대량의 데이터를 처리하는 데 유용하다. 메모리 복사를 최소화하고 데이터를 직접 공유하므로 성능이 향상될 수 있다.

사용법

공유 메모리를 사용하기 위해선 가장 먼저 생성된 key를 통해 shmget() 함수를 사용하여 공유 메모리를 생성하고 공유 메모리를 사용할 프로세스에서 shmat() 함수를 통해 메모리에 attach해야 한다.

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

#define PRO_IDFR "/home/projects/memoryTest"
#define SHM_SIZE 1024

int main() {
    key_t key = ftok(PRO_IDFR, 'ShmKey');
    int shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666);

    if (shmid == -1) {
        perror("shmget");
        exit(EXIT_FAILURE);
    }

    char *shmaddr = (char *)shmat(shmid, NULL, 0);

    if (shmaddr == (char *)-1) {
        perror("shmat");
        exit(EXIT_FAILURE);
    }

    // 공유 메모리에 데이터 쓰기
    sprintf(shmaddr, "Hello, Shared Memory!");

    // 다른 프로세스에서 공유 메모리 읽기
    pid_t pid = fork();

    if (pid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (pid > 0) {
        // 부모 프로세스에서 읽기
        printf("Parent Process: %s\n", shmaddr);
        exit(EXIT_SUCCESS);
    }

    if (pid == 0) {
        // 자식 프로세스에서 읽기
        printf("Child Process: %s\n", shmaddr);
        exit(EXIT_SUCCESS);
    }

    // 공유 메모리 분리
    if (shmdt(shmaddr) == -1) {
        perror("shmdt");
        exit(EXIT_FAILURE);
    }

    // 공유 메모리 제거
    if (shmctl(shmid, IPC_RMID, NULL) == -1) {
        perror("shmctl");
        exit(EXIT_FAILURE);
    }

    delete shmaddr;

    return 0;
}

코드를 해석하면 다음과 같다.
1. 공유 메모리를 생성한다.
- shmget() 함수를 통해 공유 메모리를 생성한다.
- 사전에 생성한 key와 define된 사이즈를 매개 변수로 사용하였다.
- IPC_CREAT 플래그는 해당 키에 해당하는 공유 메모리 영역이 없으면 새로 생성하라는 의미이다. 만약 키에 해당하는 공유 메모리 영역이 이미 존재한다면, 이 플래그는 무시된다.
- 0666 플래그는 생성된 공유 메모리 영역에 대한 퍼미션(권한)을 지정한다. 0666은 읽기와 쓰기 권한을 부여하는 값으로, 소유자, 그룹, 다른 사용자에 대해 모든 권한이 부여된다.
- IPC_CREAT 플래그 값은 01000이므로, 최종적으로 OR 연산에 의해 플래그는 01666이 된다.
2. 공유 메모리를 연결(attach)한다.
- shmat() 함수를 통해 공유 메모리를 연결한다.
- 첫 번째 매개변수는 연결하려는 공유 메모리 영역의 식별자(ID)이다. shmget() 함수를 통해 공유 메모리 영역을 생성하는데 사용된 ID를 사용해야 생성된 공유 메모리 영역에 연결할 수 있다.
- shmaddr은 연결하려는 공유 메모리를 현재 프로세스의 주소 공간에 어디에 붙일지를 지정한다. 보통 NULL을 사용하면 시스템이 알아서 적절한 주소를 선택한다.
- shmflg는 공유 메모리에 대한 플래그를 지정한다. 특별한 설정이 필요하지 않다면 0을 사용한다.
3. 공유 메모리를 분리한다
- shmdt() 함수를 통해 연결된 공유 메모리를 분리한다.
4. 공유 메모리를 제거한다.
- shmctl() 함수를 통해 공유 메모리를 제거한다.
- shmctl() 함수는 공유 메모리 식별자에 대한 제어 연산을 수행하는 함수이다.
- 첫 번째 매개 변수 shmid는 공유 메모리 식별자를 나타낸다.
- 두 번째 매개 변수 cmd는 수행할 제어 명령을 나타낸다. IPC_RMID는 공유 메모리 세그먼트를 제거하는데 사용된다.
- 세 번째 매개 변수는 struct shmid_ds * 타입으로 되어 있으며 이 구조체는 공유 메모리의 상태 정보를 저장한다. 일반적으로는 NULL을 사용한다.

0개의 댓글

관련 채용 정보