Быстрое изменение размера файла mmap

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

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

Mmap файл с MAP_PRIVATEсделать доступ только для чтения к этой памяти в нескольких потокахлибо получить мьютекс для файла, записать в память (предположим, это сделано таким образом, что читатели, которые могут читать эту память, не перепутали его)или приобретите мьютекс, но увеличьте размер файла и используйте mremap, чтобы переместить его на новый адрес (измените размер сопоставления без копирования или ненужного ввода-вывода файла).

Сумасшедшая часть входит в (4). Если вы перемещаете память, старые адреса становятся недействительными, и читатели, которые все еще читают ее, могут внезапно иметь нарушение прав доступа. Что если мы изменим считыватели, чтобы перехватить это нарушение прав доступа, а затем перезапустить операцию (т.е. не перечитывать неверный адрес, пересчитать адрес с учетом смещения и новый базовый адрес из mremap.) Да, я знаю, что это зло , но, на мой взгляд, читатели могут только успешно прочитать данные по старому адресу или потерпеть неудачу с нарушением прав доступа и повторить попытку. Если достаточно внимания уделяется, тодолжен быть в безопасности. Поскольку изменение размера не будет происходить часто, читатели в конечном итоге преуспеют и не будут зацикливаться на повторных циклах.

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

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

Я прав? Может ли это работать? Есть ли в этом преимущество перед использованием двух сопоставлений MAP_SHARED?

Ответы на вопрос(1)

Ваш ответ на вопрос