# STL 컨테이너 공유메모리 사용법
STL(Standard Template Libary) 컨테이너는 vector, deque, list, map 등의 자료구조를 가집니다.
프로세스 내 STL 컨테이너 형태에서 공유메모리에 접근하기 위해서는 boost::interprocess 라이브러리를 사용합니다.
C++ 표준 라이브러리는 메모리의 할당과 해제를 담당하는 특별한 객체를 할당자(Allocator)라고 하는데,
이 할당자를 통해 특별한 메모리 모델을 기술하며 직접적으로 프로그래머가 메모리를 얻는 방식을 추상화 시킵니다.
boost::interprocess 라이브러리를 사용하기 위해서 패키지 설치 및 공유메모리 mount 작업이 필요합니다.
테스트 환경은 CentOS를 기준으로 Qt Framework를 사용하였습니다.
# boost::interprocess 라이브러리 설치 및 공유메모리 확인
1. 패키지 설치
# yum -y install boost-deve |
2. project 파일에 아래의 명령 추가
CONFIG += thread LIBS += -L/usr/local/boost/libs -lrt |
3. /etc/fstab 파일에 mount 명령 추가
# vi /etc/fstab none /dev/shm tmpfs defaults,size=4G 0 0 |
4. 재부팅 후 확인
- /dev/shm의 크기 확인 (위 3번 과정에서 4G로 mount를 진행하였기 때문에 /dev/shm은 4G의 크기를 가집니다.)
# df -h | grep shm |
- 현재 사용 중인 Shared Memory의 크기 확인 (프로그램이 동작 중 이므로 사이즈가 점차 증가하고 있습니다.)
# ls -ash /dev/shm |
# 프로그램 실행 결과 및 소스
아래의 이미지를 기준 좌측은 공유메모리에 데이터를 Write하는 프로그램. 우측은 Read하는 프로그램 입니다.
최초 Write 프로그램에서 공유메모리의 크기를 설정하고 기록하면 Read 프로그램에서 현재 쓰여진 값을 차례로 읽어오는 과정을 거칩니다.
* Sender.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <iostream>
#include <vector>
typedef struct TestStruct
{
int firstNum;
int secondNum;
int thirdNum;
bool flag;
} test_struct;
test_struct test_value;
int main()
{
using namespace boost::interprocess;
try {
shared_memory_object::remove("SharedMemory");
//memory size adjust
size_t szLength = 480000000;
size_t szRequired = szLength * sizeof(test_struct);
size_t szRequested = (size_t) (szRequired * 1.2);
//create the shared memory
managed_shared_memory segment(create_only, "SharedMemory", szRequested);
typedef allocator<test_struct, managed_shared_memory::segment_manager>test_alloc;
typedef vector<test_struct, test_alloc>test_vector;
const test_alloc test_inst(segment.get_segment_manager());
test_vector *vector_data = segment.construct<test_vector>("data")(test_inst);
std::cout <<
"Length: " << szLength << "\n" <<
"sizeof(long): " << sizeof(test_struct) << "\n" <<
"Required: " << szRequired << "\n" <<
"Requested: " << szRequested << "\n" <<
"Allocated: " << segment.get_size() << "\n" <<
"Overhead: " << segment.get_size() - segment.get_free_memory() << "\n" <<
"Free: " << segment.get_free_memory() << "\n\n";
for (size_t i = 0; i < szLength; i++)
{
// Set "test_value" Struct Data Value
test_value.firstNum = i;
test_value.secondNum = i*10;
test_value.thirdNum = i*100;
test_value.flag = false;
// Push Data to "vector<test_struct>"
vector_data->push_back(test_value);
// Print "vector<test_struct>" Value
std::cout << "First Number: " << vector_data->at(i).firstNum << "\n"
<< "Sencond Number: " << vector_data->at(i).secondNum << "\n"
<< "Third Number: " << vector_data->at(i).thirdNum << "\n"
<< "Flag : " << vector_data->at(i).flag << "\n";
}
}
catch (...) {
shared_memory_object::remove("SharedMemory");
throw;
}
shared_memory_object::remove("SharedMemory");
return 0;
}
|
* Receiver.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
#include <boost/interprocess/managed_shared_memory.hpp> #include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <vector>
typedef struct TestStruct
{
int firstNum;
int secondNum;
int thirdNum;
bool flag;
} test_struct;
std::vector<test_struct> save_vector;
test_struct test_value;
int main()
{
using namespace boost::interprocess;
try
{
managed_shared_memory segment(open_only, "SharedMemory"); //segment name
typedef allocator<test_struct, managed_shared_memory::segment_manager>test_alloc;
typedef vector<test_struct, test_alloc>test_vector;
test_vector *vector_data = segment.find<test_vector>("data").first;
for(int i = 0; i < 100.; i++)
{
std::cout << "First Number: " << vector_data->at(i).firstNum << "\n"
<< "Sencond Number: " << vector_data->at(i).secondNum << "\n"
<< "Third Number: " << vector_data->at(i).thirdNum << "\n"
<< "Flag : " << vector_data->at(i).flag << "\n";
}
segment.destroy<test_vector>("data");
}
catch (...)
{
shared_memory_object::remove("SharedMemory");
throw;
}
shared_memory_object::remove("SharedMemory");
return 0;
}
|
'C · C++' 카테고리의 다른 글
Multi-thread 구현 시 strtok() 함수 오류 (0) | 2020.09.14 |
---|---|
헤더와 라이브러리 비교 (1) | 2020.06.03 |
이차원 포인터와 포인터 배열 및 배열 포인터 (0) | 2020.04.24 |
배열과 포인터의 메모리 차이 (1) | 2020.04.22 |
const int*와 int* const 차이 (2) | 2020.04.21 |