WedX - журнал о программировании и компьютерных науках

повысить межпроцессную оболочку до распределителя

У меня есть мультииндексный контейнер в shared_memory

//Create hash
typedef boost::multi_index::multi_index_container<
  My_Key,
  My_Key_hash_indices,
  bip::allocator<MyKey, bip::managed_shared_memory::segment_manager>
> MyGlobalHash;

Мне нужно в соответствии с конфигурацией использовать одно из следующих:

  1. bip::managed_mapped_file
  2. bip::managed_shared_memory

Есть ли способ сделать это без создания обоих типов, например, создать класс-оболочку для распределителя и наследовать для обоих типов.

Больше кода на https://coliru.stacked-crooked.com/a/09ea79752512fad8


Ответы:


1

Нет, тебе это не нужно. Быстрое статическое утверждение узнает, что тип менеджера сегментов по умолчанию тот же:

static_assert(std::is_same<
        bip::managed_shared_memory::segment_manager,
        bip::managed_mapped_file::segment_manager>{}, "incompatible segments");

Итак, вы можете просто использовать один:

using SegmentManager = bip::managed_shared_memory::segment_manager;

Демо

Прямой эфир на Coliru

#include <iostream>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/interprocess/allocators/allocator.hpp>

namespace bip = boost::interprocess;

static_assert(std::is_same<
        bip::managed_shared_memory::segment_manager,
        bip::managed_mapped_file::segment_manager>{}, "incompatible segments");
using SegmentManager = bip::managed_shared_memory::segment_manager;

struct X {
    int i = 0;
};

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>

namespace bmi = boost::multi_index;

using Table = bmi::multi_index_container<X,
      bmi::indexed_by< bmi::ordered_unique< bmi::tag<struct byI>, bmi::member<X, int, &X::i> > >,
      bip::allocator<X, SegmentManager>
  >;

void dump(Table const& t) {
    std::cout << "table: ";
    for(auto& x : t)
        std::cout << x.i << "; ";
    std::cout << std::endl;
}

void run_test(Table& table) {
    dump(table);

    if (table.empty()) {
        table.insert({{1}, {2}, {3}, {4}});
    } else {
        table.insert({5});
    }

    dump(table);

    table.erase(table.begin());
    dump(table);
}

int main() {
    {
        bip::managed_shared_memory segment(bip::open_or_create, "msm", 10ul<<20);
        run_test(*segment.template find_or_construct<Table>("name")(segment.get_segment_manager()));
    }
    {
        bip::managed_mapped_file segment(bip::open_or_create, "mmf", 10ul<<20);
        run_test(*segment.template find_or_construct<Table>("name")(segment.get_segment_manager()));
    }
}

Печатает (в моей системе), например:

table: 2; 3; 4; 
table: 2; 3; 4; 5; 
table: 3; 4; 5; 
table: 2; 3; 4; 
table: 2; 3; 4; 5; 
table: 3; 4; 5; 
29.05.2018
  • Спасибо за ответ, да, я могу, но проблема в том, что с предложенным вами решением мне нужно иметь класс/функцию-оболочку, которая имеет оба типа указателя и выполняет if/else в соответствии с типом сегмента, который мне нужно использовать - это было мой вопрос (есть ли способ сделать это, не создавая оба типа) 30.05.2018
  • Дэвид, я не создавал никаких оберток. Есть только Table, которые я демонстрирую с обоими типами сегментов без ЛЮБОЙ разницы. 30.05.2018
  • В моем коде много места, где используется таблица. В основном, если бы вам пришлось использовать тот или иной тип разделяемой памяти, вам нужно было бы написать if(mappped_file) run_test‹bip::managed_mapped_file›(mmf); иначе run_test‹bip::managed_shared_memory›(msm); Это то, чего я хочу избежать, используя if else 30.05.2018
  • Ой. Кажется, я скопировал не совсем окончательную версию кода. Поверьте, у меня было много куда более сложных версий :) Фиксирую ответ. 30.05.2018
  • Ладно, в целом причин для беспокойства не было. Всего несколько избыточных параметров шаблона, которые на самом деле не использовались. Надеюсь, теперь стало понятнее. 30.05.2018
  • Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]