Проверьте, что boost :: interprocess :: vector имеет достаточную емкость перед записью? - PullRequest
0 голосов
/ 16 мая 2018

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

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();
}

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

1 Ответ

0 голосов
/ 17 мая 2018

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

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

enter image description here

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

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

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

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

...