shared memory 를 사용하는 두가지 방법

Shared Memory 를 사용하는 방식은 두가지가 있습니다.

우리가 가장 기본적으로 알고 있었던 shmget 을 이용하여 생성하는 System V 방식과, shm_open 을 사용하는 posix 방식이 그것입니다.

사용하는 sample 들은 여기저기 블로그나 웹에서 찾기 쉬우니 제가 경험으로 얻은 좀 더 중요한 사항들을 기록해봅니다.

1. system V 방식
shmget -> shmat -> shmdt

2. posix 방식
shm_open -> ftruncate -> mmap -> munmap

두 방식의 가장 큰 차이점은 system v 방식의 경우 shm segment 를 만들고 해당 id 를 통해 segment 들을 구분 관리하는 것에 비해, posix 방식은 shm segment 에 대응하는 file 을 통해 memory 까지 관리하는 방식이라는 것입니다.

즉, posix 방식은 shm  영역을 하나 잡고 파일을 하나 생성하여 해당 shm memory 영역을 파일에 mapping 하여 사용하는 구조입니다.

 

system v 방식으로도 충분해보이는데 왜 posix 방식이 또 필요했을까요 ?

Intel X86 기반의 Redhat Linux 6.2 버전 기준으로 system v 방식의 경우 shared memory segment 의 최대 갯수가 32K 로 제한되어 있습니다. 즉, shared memory segment 갯수를 32K 이상 만들지 못한다는 것입니다.

shmmni 등의 값을 수정해서 될 문제가 아니라 kernel 에 hard coding 값으로 고정되어 있습니다.

대부분의 경우 이 정도 숫자의 shm segment 를 사용할 일은 없겠지만, 특정 대형 시스템의 경우 이 제한때문에 posix 방식으로 변경하였습니다.

물론 파일 갯수는 거의 무제한으로 사용할 수 있기 때문에 posix 방식을 통해 shm segment 를 생성하는 것은 거의 제한이 없지만, 시스템의 limit 들을 조정할 필요는 있습니다.

예를 들면, ulimit -n 을 통해 open files 에 대한 사용자 제한값을 늘린다거나, /proc/sys/vm/max_map_count 의 값을 늘려서 프로세스가 mmap 및 malloc 등 memory map 사용 갯수에 제한을 받지 않도록 해야 합니다.

이러한 posix 방식을 사용해보니 system v 대비하여 성능 상 거의 차이가 없었습니다.

일부 업무에서는 오히려 성능이 괜찮기도 했구요.

shared memory 를 눈에 보이는 file 형태로 관리하고 싶다면 posix 방식을 사용해 보십시오.

권장합니다.

PS. posix 방식은 ipcs -m 명령을 통해 보이지 않습니다. /dev/shm 아래에 파일을 생성하고 관리해야 합니다.

You may also like...

0 0 votes
Article Rating
Subscribe
Notify of
guest
3 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
구름과비21

posix 방식 사용 시 유념해야할 점이 있습니다.
1. paging 을 고려할 필요가 없다면 mmap 에서 MAP_LOCKED 옵션을 빼는 것이 좋습니다. 성능 jitter 현상이 확연히 줄어듭니다.
2. max_map_count 를 작게 잡으면 시스템의 메모리와 프로세스의 메모리 사용량이 작은 상황에서도 memory alloc 시에 메모리 부족인 것 처럼 에러를 만날 수 있습니다.
3. posix 방식이건 system v 방식이건 할당 segment size 를 크게 잡으면 해당 메모리를 한번에 할당하는 것이 아닙니다. memory 에 write 를 해나가면서 시스템에서 조금씩 조금씩 필요한만큼 할당해줍니다.
그래서, memory 가 부족할 경우는 프로그램적으로는 이미 할당된 영역인데 실제 write 하려고 포인터로 접근을 하게 되면 프로그램이 갑자기 sigbus 로 죽어버릴 수 있습니다. 이에 대한 대책을 별도로 마련해야 합니다.

구름과ጆ

posix 방식 사용 시 유념해야할 점이 있습니다.
1. paging 을 고려할 필요가 없다면 mmap 에서 MAP_LOCKED 옵션을 빼는 것이 좋습니다. 성능 jitter 현상이 확연히 줄어듭니다.
2. max_map_count 를 작게 잡으면 시스템의 메모리와 프로세스의 메모리 사용량이 작은 상황에서도 memory alloc 시에 메모리 부족인 것 처럼 에러를 만날 수 있습니다.
3. posix 방식이건 system v 방식이건 할당 segment size 를 크게 잡으면 해당 메모리를 한번에 할당하는 것이 아닙니다. memory 에 write 를 해나가면서 시스템에서 조금씩 조금씩 필요한만큼 할당해줍니다.
그래서, memory 가 부족할 경우는 프로그램적으로는 이미 할당된 영역인데 실제 write 하려고 포인터로 접근을 하게 되면 프로그램이 갑자기 sigbus 로 죽어버릴 수 있습니다. 이에 대한 대책을 별도로 마련해야 합니다.

라면사냥

posix 방식이 개발측면에서 더 좋은 것은 shared memory 영역에 대해 정리하는 코스트가 없는 것입니다. 즉 mmap 을 사용하기 때문에 process 종료시 shared memory가 자동으로 정리가 됩니다.

3
0
Would love your thoughts, please comment.x
()
x