본문 바로가기

리눅스 커널/기타

[C++] 리눅스 System V 공유메모리

[1. 개요]

리눅스 공유메모리의 한 종류인 System V 공유메모리의 간단한 사용 방법 및

유의 사항을 정리하도록 한다.


[2. 생성]

#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>

int main()
{
        const int id = shmget(0x12345678, 4096, IPC_CREAT | IPC_EXCL | 0666);
        // 할당할 메모리 공간의 크기
        // 생성, 이미 존재하면 실패, 접근 권한
        if (id == -1) {
                perror("shmget fail");
                return 1;
        }
        
        // 공유메모리 세그먼트에 attach
        void* ptr = shmat(id, NULL, 0);
        if (ptr == (void*)(-1)) {
                perror("shmat fail");
                return 2;
        }

        strcpy((char*)(ptr), "hello");

#ifdef DEL
        if (shmctl(id, IPC_RMID, NULL) == -1) {
                perror("shmctl fail");
                return 3;
        }
#endif

        // 공유메모리 세그먼트를 detach
        shmdt(ptr);

        return 0;
}

 

[3. 접근]

#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>

int main()
{
        const int id = shmget(0x12345678, 4096, 0444);
        if (id == -1) {
                perror("shmget fail");
                return 1;
        }

        void* ptr = shmat(id, NULL, 0);
        if (ptr == (void*)(-1)) {
                perror("shmat fail");
                return 2;
        }

        const char* str = (const char*)(ptr);
        std::cout << str << std::endl;

        shmdt(ptr);

        return 0;
}

[4. 삭제]

공유메모리 세그먼트의 삭제는 shmctl 을 통해서 이루어 진다.

shmctl 과 여러 옵션을 통해 공유메모리에 대한 상세한 컨트롤이 가능한데,

여기서 IPC_RMID 는 공유메모리 세그먼트를 삭제하는 것이 아니라, 삭제 해줄 것을 (커널에?) 요청하는 것이다.

정리하면, 

  • shmctl 이 정상 호출 된 경우, 공유메모리 세그먼트가 삭제되는 것이 아니라,
  • 더 이상 참조 되지 않을 때 삭제 할 것을 요청하는 것이다.
  • 즉, shmctl 을 통하여 삭제를 요청하지 않는다면, attach 된 프로세스가 없어도 공유메모리는 남아 있게 된다.

이러한 특성을 통해, 프로세스가 종료되어도 공유메모리는 남아 있을 수 있다.

그러나, 프로세스를 재시작 해야하는 경우 그리고 이때 IPC_EXCL 옵션으로 공유메모리를 생성하는 경우,

정상 실행이 되지 않을 수 있다.

 

이 경우에는, shmget 으로 공유메모리 세그먼트를 생성하고, detach 하기 전에,

shmctl 을 먼저 호출 하는 방식을 고려할 수 있다.

물론, shmctl 을 호출하는 쪽은 공유메모리를 생성하는 프로세스에서 하도록 한다.

 

공유메모리 세그먼트 삭제를 요청한 경우, 더 이상의 새로운 attach 는 허용되지 않는다.


[5. 기타 참고 사항]

  • ftok()
  • ipcs
  • ipcmk
  • ipcrm
  • /proc/sysvipc/msg
  • /proc/sysvipc/sem
  • /proc/sysvipc/shm

윈도우 API 와 달리, 이미 할당된 공유메모리 세그먼트의 크기를 알 수 있다.

  • shmctl 과 IPC_STAT 을 이용하여...

POSIX 방식의 공유메모리도 있음. tmpfs 를 이용하여 /dev/shm 에 생성 됨.

  • shm_open
  • shm_unlink
  • mmap
  • munmap
  • ftruncate

 

'리눅스 커널 > 기타' 카테고리의 다른 글