2013-01-04 4 views
2

메모리 매핑 된 파일 내에 할당 된 부스트 multi_index_container를 신뢰할 수 있습니까? 같은 endianess를 가진 컴퓨터간에이 "데이터베이스"가 가능합니까?파일에 저장된 부스트 multi_index_container의 지속성

+0

C++ 표준은 내가 아는 한 "메모리 매핑 된 파일"개념이 없기 때문에 매우 구체적인 플랫폼으로 들립니다. :). 내가 가질 수있는 걱정은 "매번 같은 기본 주소에있게 될 것인가?"라고 생각하고 나는 그것을 의심 할 것입니다. – Yakk

+0

예. 늘어나는만큼 내가 어떻게 mmap 또는 부스트 래퍼 작품을 항상 동일한 기본 주소 (0 또는 제공된 오프셋) 얻을 것이다 이해합니다. – Dejwi

+0

필자는 파일의 오프셋이 아니라 메모리의 오프셋에 대해 말하고 있습니다. 부스트의 경우 힌트를 전달할 수 있습니다 :'mapped_file_params :: hint',하지만 단지 힌트 일뿐입니다. 그래서 안됩니다. 안전하지 않습니다. – Yakk

답변

2

아니요, 이것은 안전하지 않습니다. 메모리 매핑 된 파일의 첫 번째 바이트 주소는 호출간에 동일하지 않을 수 있습니다.

부스트의 메모리 맵 파일은 hint이지만 힌트 일뿐입니다.

첫 번째 호출에서 메모리는 0xBAADF00D에 위치 할 수 있습니다. 두 번째 호출에서는 0xF00DBAAD에 위치 할 수 있습니다. 구조 내의 포인터는 0xF00DBAAD이 아닌 0xBAADF00D 주위의 메모리를 가리 키므로 더 이상 유효하지 않습니다. 심각한 문제로

, 그것은 hint은 일반적으로 순종 하듯이 시험에서 일반적으로 일, 수 -하지만 때로는 이미 메모리 주소에서 물건이있을 것이며, hint가있을 것이다는 무시한다.

(이 부분을 정말 어렵게 만드는 부분이 있습니다.하지만 위의 내용은 꽤 실행 불가능합니다).

이제 이와 같은 전략은 효과적 일 수 있지만 문제의 데이터 구조에 대한 내재적 인 조사가 필요합니다. 데이터 구조가 올바른 오프셋을 갖기 위해서는 DLL readdressing과 같은 단계를 거쳐야하며, 그 시점까지는 평면으로 직렬화 할 수도 있습니다.

+0

이 예제를 기반으로합니다 : http://www.boost.org/doc/libs/1_52_0/libs/multi_index/example/ip_allocator.cpp 네임 스페이스 bip = boost :: interprocess; bip :: allocator 문자열, 벡터 등을 할당하는 자동차를 사용하지 않으시겠습니까? – Dejwi

+0

@Dejwi 물론, 물건은 메모리 매핑 된 파일에서 오프셋으로 할당됩니다. 그런 다음 디스크에 저장됩니다. 그런 다음 다른 사람이 다른 * 오프셋으로로드합니다. 무슨 일이야? 아주 단순한 경우를 살펴 보자 :'int *'는 파일 내에서'int '를 가리키고,'0xBAADF00D'에 매핑된다. 원래의 경우,'int *'를 역 참조 할 때 어떻게 될까? 이제 파일은 기본 주소'0xF00DBAAD'로로드됩니다 - 어떻게됩니까? – Yakk

+1

오프셋 문제는 일반 작업이 아닌 [오프셋 포인터] (http://www.boost.org/doc/html/boost/interprocess/offset_ptr.html)를 사용하는 데이터 구조를 사용하여 재 지정 또는 기타 작업을 수행하지 않고 극복 할 수 있습니다. Boost.MultiIndex는 그렇게 할 준비가되어 있습니다. –

0

당신이 원하는 것은 전송하는 경우 multi_index 한 컴퓨터에서 가장 좋은 것은 사용 상자 밖으로 작동 Boost.Serialization, 또 다른에 :

http://www.boost.org/doc/libs/1_60_0/libs/multi_index/doc/tutorial/creation.html#serialization

#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 
#include <fstream> 
... 
void save(const employee_set& es) 
{ 
    std::ofstream ofs("data"); 
    boost::archive::text_oarchive oa(ofs); 
    oa<<es; 
} 

void load(employee_set& es) 
{ 
    std::ifstream ifs("data"); 
    boost::archive::text_iarchive ia(ifs); 
    ia>>es; 
} 
... 
employee_set es; // a multi_index type 
... // fill it with data 
save(es); 
... 
employee_set restored_es; 
load(restored_es); 
0

도움으로 Boost.Interprocess's memory mapped files과 약간의주의가 지속될 수 있습니다. multi_index_container s; 서로 다른 주소에있는 매핑 문제는 포인터가 아닌 offsets을 사용하여 극복 할 수 있으며 Boost.MultiIndex는이를 처리 할 준비가되어 있습니다. this example을 참조하십시오. 한 번에 여러 프로세스의 액세스로 단순한 데이터베이스가 구현됩니다.

지속성이 매우 깨지기 쉬운 접근 방식의 메모리는 이러한 매개 변수가 정확히 동일한 경우에만 작동으로, 파일을 매핑 사용했다 :

  • 시스템 아키텍처
  • 운영 체제 버전
  • 컴파일러 버전
  • 컴파일 매개 변수 (예 : 패딩에 영향을 미칠 수 있음)
  • ABI가 변경 될 수 있으므로 사용 된 모든 관련 라이브러리 버전 (부스트 포함) 버전
  • 내가 @alfC에 의해 제안

모든 것이 Boost.Serialization를 사용하여, 고려 :-) 잊고 다른 측면에 걸쳐 아마 다른 환경에서 휴대용 지속성을위한 최상의 솔루션입니다.

  • 같은 시스템에서 동일한 구조를 사용하는 여러 프로세스 (이상적으로는 동일한 실행 파일)의 컨텍스트 내에서 세션에있는 경우, 컨테이너를 메모리 맵핑하십시오.
  • 일단 세션이 끝나면 (또는 충돌 등을 방지하기 위해 너무 자주) Boost.Serialization을 사용하여 이식성있게 유지하십시오.