2013-10-23 3 views
1

필자는 두 개의 프로그램 중 아주 작은 예가 있습니다. 하나는 공유 메모리 세그먼트를 쓰고 다른 하나는 읽는 것입니다. std::string (및 기타 컨테이너)과 관련하여 잠재적으로 문제가 있음을 알고 있으므로 인 boost::interprocess::string을 시도했습니다. 나는 이것이 정말로 근본적이고 단순한 무엇인가를 놓치고 있다고 확신하지만 그것을 볼 수 없다!부스트 IPC 문자열 길이 segfault?

어쨌든 시놉시스는 문자열이 작을 때 (첫 번째 프로그램은 SSO보다 크다고 생각하지만) 첫 번째 프로그램을 실행하면 메모리가 쓰고 두 번째는 완전히 잘 읽습니다. 그러나이 예제 에서처럼 문자열을 꽤 크게 만들면 읽기 프로그램 segfaults가 발생합니다. 모두 writeipc.cc 아래. 코드를 읽고 쓸 동일한 프로세스에 있지만 다른 기능은 (그래서 IPC를 통해 제외한 모든 데이터를 공유하지 않으면 나는이 함께 성공을

#include <boost/interprocess/managed_shared_memory.hpp> 
#include <boost/interprocess/containers/string.hpp> 
#include <iostream> 
#include <utility> 

int main() 
{ 
    typedef boost::interprocess::string bi_string; 

    boost::interprocess::shared_memory_object::remove("Test"); 
    boost::interprocess::managed_shared_memory managed_shm(boost::interprocess::create_only, "Test", 65536); 


    bi_string* i = managed_shm.construct<bi_string>("string")("abcdefghijklmnopqrstuvwxyzaskl;dfjaskldfjasldfjasdl;fkjwrotijuergonmdlkfsvmljjjjjjjjjjjjjj"); // make smaller (ie "jjjjjjjjjjjjjj" and test passes 
    std::cout << "inserting into shm" << *i << std::endl; 

    std::pair<bi_string*, size_t> q = managed_shm.find<bi_string>("string"); 
    std::cout << *q.first << std::endl; 
while(true) 
    std::cout << "still running"; // hack to keep process running (not required) 
} 

readipc.cc

#include <boost/interprocess/managed_shared_memory.hpp> 
#include <boost/interprocess/containers/string.hpp> 
#include <iostream> 

int main() 
{ 
    typedef boost::interprocess::string bi_string; 
    boost::interprocess::managed_shared_memory managed_shm(boost::interprocess::open_only, "Test"); 

    std::pair<bi_string*, std::size_t> p = managed_shm.find<bi_string>("string"); 
    std::cout << "existing value" << *p.first << std::endl; 

} 
+0

'쓰기'가 완료된 후 * '읽었습니까?' – Jarod42

+0

예, 물론입니다. 나는 할당 자에게 아마도 그렇게 생각한다. 나는이 배경을 더 자세히 살펴볼 것이지만, ipc 문자열을 사용하고 ipc :: string에서 std :: string 또는 무엇이든 어쩌면 포드 유형으로 전환하는 것이 가장 쉽습니다. – dirvine

답변

3

OK, 대답이 할당 관련이 있었다.

내가 어떻게하는 Begi 다른 사람이 빨리 찾을 수 있도록 답이 무엇을 믿는 게시하고 n IPC를 사용합니다. 나는 프로세스에 대해 잘 설명하지 못하는 웹에 대한 많은 예제를 발견했으며 정상적인 문자열 등을 사용하는 것이 괜찮을 것이라는 인상을주었습니다. 다른 프로세스에서 읽을 때까지 나타납니다. 따라서 솔루션을 완전히 구현하려면 약간의 추가 단계가 필요합니다.

본질적으로 일반적인 stl 유형 컨테이너에서 제공하는 할당자를 사용할 수 없습니다. 이것은 문서화되어있다 here

어디서 할당 되는가?

Boost.Interprocess construct<>, find_or_construct<>... functions. These functions place a C++ object in the shared memory/memory mapped 

파일 :

Boost.Interprocess 용기가 공유 메모리에 저장하고/메모리 동시에 두 가지 메커니즘을 사용 ... 등의 파일을 매핑. 그러나 이것은 객체 만 배치하지만이 객체가 동적으로 할당 할 수있는 메모리는 배치하지 않습니다. 공유 메모리 할당 자. 이를 통해 공유 메모리/메모리 맵핑 된 파일 부분을 할당하여 컨테이너가 새로 삽입 된 요소를 저장하기 위해 동적으로 조각 된 메모리를 할당 할 수 있습니다.

이 그 용기, 파일 공유 메모리 또는 메모리 매핑 ( Boost.Interprocess 문자열을 포함) Boost.Interprocess 컨테이너를 배치하는 것을 의미해야합니다

Define their template allocator parameter to a Boost.Interprocess allocator. 
Every container constructor must take the Boost.Interprocess allocator as parameter. 
You must use construct<>/find_or_construct<>... functions to place the container in the managed memory. 

첫 번째 두 지점 당신 만 할 경우 구성 <> 또는 find_or_construct <>을 사용하지 마십시오. 컨테이너는 프로세스에만 배치되지만 포함 된 유형의 메모리는 공유 된 메모리/메모리 맵핑 파일에서 할당됩니다.

나는 위의 실종이 지금 우리가 할당을 얻을 수있을 때 저장 될 수있는 문자열입니다

namespace bi = boost::interprocess; 
typedef bi::allocator<char, bi::managed_shared_memory::segment_manager> CharAllocator; 
typedef bi::basic_string<char, std::char_traits<char>, CharAllocator> bi_string; 

이었다 무엇

here을 찾을 수 있습니다 예를 들어, 기능의 몇 가지를 만들었습니다 그것을 위해. 이것은 지금 charallocator가 공유 메모리 위치에서 작동하고 제대로 다시 읽을 수 할 수있을 것입니다 문자열 형식을 구성하는 데 사용할 수있는이

bi::managed_shared_memory segment(bi::create_only, "shm name", 
                65536); 
    // Create an object of Type initialized to type 
    CharAllocator charallocator(segment.get_segment_manager()); 

처럼 메모리 세그먼트에서 할당을 얻는 것을 의미한다. 문자열은 다음과 같이 작성됩니다.

bi_string str(charallocator); 

그런 다음이 문자열에 cstring을 할당 할 수 있습니다. 그래서 예를 들어 std :: string test ("테스트 문자열");

str = test.c_str(); 

당신이 당신의 문자열이

segment.construct<bi_string>("some name")(str) 

당신은 공유 메모리 저장소에 많은 세그먼트를 저장할 수있는 저장됩니다 세그먼트를 구성합니다. 나는 이것이 다른 사람들을 돕기를 바랍니다. 코드는 위의 링크에서 테스트를 통해 모두 사용할 수 있습니다.