1

Boost::Interprocess のドキュメントと Google 検索をくまなく調べた後、問題の理由/回避策を見つけたと思います。私が理解しているように、私が見つけたものはすべてこれを暗示しているようですが、出てきて「これを行う理由は...」とは言いません。しかし、誰かがこれを確認できるなら、私はそれを感謝します.

並列化されたアプリケーションで高速なパフォーマンスを実現するためにメモリに格納される大量の情報を表す一連のクラスを作成しています。1 台のマシンで同時に実行されるデータと複数のプロセスのサイズのため、共有メモリに Boost::Interprocess を使用して、構造の単一のコピーを保持しています。

Boost::Interprocess のドキュメントと例を見たところ、共有メモリ文字列、文字列ベクトル、int ベクトル ベクトルなどのクラスを型定義していました。例でそれらを「使用」するときは、アロケータを渡して構築するだけで、多分彼らが他の場所で構築した1つのアイテムを挿入します。このページのように: http://www.boost.org/doc/libs/1_42_0/doc/html/interprocess/allocators_containers.html

そこで、彼らの例に従って、共有メモリ クラスの typedef を含むヘッダー ファイルを作成しました。

namespace shm {
    namespace bip = boost::interprocess;

    // General/Utility Types
    typedef bip::managed_shared_memory::segment_manager segment_manager_t;
    typedef bip::allocator<void, segment_manager_t> void_allocator;

    // Integer Types
    typedef bip::allocator<int, segment_manager_t> int_allocator;
    typedef bip::vector<int, int_allocator> int_vector;

    // String Types
    typedef bip::allocator<char, segment_manager_t> char_allocator;
    typedef bip::basic_string<char, std::char_traits<char>, char_allocator> string;
    typedef bip::allocator<string, segment_manager_t> string_allocator;
    typedef bip::vector<string, string_allocator> string_vector;
    typedef bip::allocator<string_vector, segment_manager_t> string_vector_allocator;
    typedef bip::vector<string_vector, string_vector_allocator> string_vector_vector;
}

次に、ルックアップ テーブル クラスの 1 つについて、次のように定義します。

class Details {
public:
    Details(const shm::void_allocator & alloc) :
        m_Ids(alloc),
        m_Labels(alloc),
        m_Values(alloc) {
    }
    ~Details() {}

    int Read(BinaryReader & br);

private:
    shm::int_vector m_Ids;
    shm::string_vector m_Labels;
    shm::string_vector_vector m_Values;
};

int Details::Read(BinaryReader & br) {
    int num = br.ReadInt();

    m_Ids.resize(num);
    m_Labels.resize(num);
    m_Values.resize(num);

    for (int i = 0; i < num; i++) {
        m_Ids[i] = br.ReadInt();
        m_Labels[i] = br.ReadString().c_str();

        int count = br.ReadInt();
        m_Value[i].resize(count);
        for (int j = 0; j < count; j++) {
            m_Value[i][j] = br.ReadString().c_str();
        }
    }
}

しかし、コンパイルすると、次のエラーが発生します。 'boost::interprocess::allocator<T,SegmentManager>::allocator' : no appropriate default constructor available

resize()これは、ベクター オブジェクトの呼び出しによるものです。型にはallocator空のコンストラクターがなく ( を受け取るconst segment_manager_t &)、各場所の既定のオブジェクトを作成しようとしているためです。したがって、それが機能するためには、アロケーター オブジェクトを取得し、デフォルト値オブジェクトを に渡す必要がありますresize。このような:

int Details::Read(BinaryReader & br) {
    shm::void_allocator alloc(m_Ids.get_allocator());
    int num = br.ReadInt();

    m_Ids.resize(num);
    m_Labels.resize(num, shm::string(alloc));
    m_Values.resize(num, shm::string_vector(alloc));

    for (int i = 0; i < num; i++) {
        m_Ids[i] = br.ReadInt();
        m_Labels[i] = br.ReadString().c_str();

        int count = br.ReadInt();
        m_Value[i].resize(count, shm::string(alloc));
        for (int j = 0; j < count; j++) {
            m_Value[i][j] = br.ReadString().c_str();
        }
    }
}

これは最善/正しい方法ですか?それとも私は何かを逃していますか。

ありがとう!

4

0 に答える 0