Перед записью проверьте, что boost::interprocess::vector имеет достаточную емкость?

Я использую общий вектор для обмена объектами в памяти:

using ShmemAllocator = bip::allocator<T, bip::managed_shared_memory::segment_manager>;
using MyVector = bip::vector<T, ShmemAllocator>;

bip::permissions perm;
perm.set_unrestricted();
segment.reset(new bip::managed_shared_memory(bip::open_or_create, shared_memory_name, numBytes, 0, perm));

const ShmemAllocator alloc_inst(segment->get_segment_manager());
vec = segment->find_or_construct<MyVector>(shared_vector_name)(alloc_inst);

Обратите внимание, что вектор создается внутри объекта managed_shared_memory, и он создается путем указания количества байтов, а не количества элементов вектора.

Затем я записываю элементы в вектор:

int write(const std::vector<T>& vec)
{
    bip::scoped_lock<bip::named_mutex> lock(*sdc.mutex);

    for(const auto& item : vec)
    {
        sdc.vec->push_back(item);
    }

    sdc.cond_empty->notify_all();
}

Каков самый безопасный способ проверить, достаточно ли у меня места для записи всех моих элементов перед записью? Мне бы очень хотелось избежать простого назначения большого количества байтов в надежде, что я никогда не нажму!


person user997112    schedule 16.05.2018    source источник
comment
позвонить vector::reserve?   -  person user7860670    schedule 16.05.2018
comment
@VTT, это может потерпеть неудачу. Проверка capacity() уже ближе   -  person sehe    schedule 17.05.2018
comment
@sehe Я не видел вашего комментария и реализовал то, что, вероятно, предлагает VTT, посредством чего я пытаюсь сделать резерв (vec.size() + newVec.size()), и если это не удается, я ловлю и возвращаю false. Является ли capacity() правильным способом реализации того, что я в итоге сделал?   -  person user997112    schedule 18.05.2018
comment
capacity() — правильный ответ на вопрос, выделенный полужирным шрифтом Каков самый безопасный способ проверить, достаточно ли у меня места для записи всех элементов перед записью?. Однако предыстория предполагает, что вы хотите знать, как мне убедиться, что мой сегмент памяти достаточно велик, чтобы содержать мои данные (например, вектор)? что я ответил в мой вопрос.   -  person sehe    schedule 18.05.2018


Ответы (1)


Обратите внимание, что вектор создается в объекте manage_shared_memory, и он создается путем указания количества байтов, а не количества элементов вектора.

Прямой формулы не существует, поскольку накладные расходы менеджера сегментов могут быть значительными и зависят от шаблонов распределения: в в этом более старом ответе я демонстрирую это весьма наглядно:

введите здесь описание изображения

Имея это в виду, вы, вероятно, можете провести некоторое тестирование на предполагаемой платформе и определить фактический требуемый размер.

Однако вы также можете забыть об этом и помнить, что это все равно виртуальная память. Просто зарезервируйте ТБ или три, и ничего не должно быть сопоставлено/зафиксировано, если вы не используете эти страницы.

Если вы хотите использовать managed_mapped_file, вы можете использовать ftruncate для создания разреженного файла Very Large™ (т. е. без фактически выделенных блоков) и использовать его точно так же.

Не все файловые системы поддерживают разреженные файлы, но все основные файловые системы поддерживают (NTFS, ext2/3/4 и т. д.). Обычно, если разреженные файлы не поддерживаются, mmap также не поддерживается (например, сетевые файловые системы или высокоуровневые драйверы предохранителей).

person sehe    schedule 16.05.2018