Мне нужно без копирования изменить размер очень большого файла mmap, но при этом разрешить одновременный доступ к потокам чтения.
] Самый простой способ - использовать два сопоставления MAP_SHARED (увеличить файл, затем создать второе сопоставление, включающее увеличенную область) в одном и том же процессе над тем же файлом, а затем отменить сопоставление старого сопоставления после того, как все считыватели, которые могли получить к нему доступ, завершили работу. Однако мне любопытно, может ли приведенная ниже схема работать, и если да, то есть ли в ней какие-либо преимущества.
Сумасшедшая часть co mes in at (4). Если вы перемещаете память, старые адреса становятся недействительными, и читатели, которые все еще ее читают, могут внезапно получить нарушение доступа. Что, если мы модифицируем считыватели, чтобы перехватить это нарушение прав доступа, а затем перезапустить операцию (т.е. не перечитывать неверный адрес, повторно вычислять адрес с учетом смещения и нового базового адреса из mremap.) Да, я знаю, что это зло, но, на мой взгляд, читатели могут только успешно прочитать данные по старому адресу или выйти из строя с нарушением доступа и повторить попытку. Если приняты необходимые меры, то должно быть безопасным. Поскольку изменение размера будет происходить нечасто, считыватели в конечном итоге добьются успеха и не застрянут в цикле повторных попыток.
Проблема может возникнуть, если это старое адресное пространство будет повторно использовано, пока читатель все еще имеет указатель на него. Тогда нарушения прав доступа не будет, но данные будут неверными, и программа войдет в область неопределенного поведения, наполненную единорогами и конфетами (где обычно нет ни единорогов, ни конфет).
Но если вы полностью контролировали распределение и могли бы сделать будучи уверенным, что любые выделения, которые происходят в течение этого периода, никогда не будут повторно использовать это старое адресное пространство, тогда это не должно быть проблемой, и поведение не должно быть неопределенным.
Я прав? Может это сработать? Есть ли у этого преимущества перед использованием двух сопоставлений MAP_SHARED?