edimensionamento rápido de um arquivo mm

Eu preciso de um redimensionamento sem cópia de um arquivo mmap muito grande e ainda assim permitir acesso simultâneo a threads do leito

A maneira mais simples é usar dois mapeamentos MAP_SHARED (aumentar o arquivo, criar um segundo mapeamento que inclua a região crescida) no mesmo processo sobre o mesmo arquivo e remover o mapeamento do mapeamento antigo assim que todos os leitores que poderiam acessá-lo forem concluídos. No entanto, estou curioso para saber se o esquema abaixo pode funcionar e, em caso afirmativo, existe alguma vantagem niss

mmap um arquivo com MAP_PRIVATEdo acesso somente leitura a esta memória em vários threads adquira um mutex para o arquivo, escreva na memória (suponha que isso seja feito de uma maneira que os leitores, que podem estar lendo essa memória, não sejam prejudicados por ele)u adquira o mutex, mas aumente o tamanho do arquivo e use o mremap para movê-lo para um novo endereço (redimensione o mapeamento sem copiar ou copiar E / S desnecessárias do arquivo

A parte louca entra em (4). Se você mover a memória, os endereços antigos se tornam inválidos e os leitores, que ainda estão lendo, podem repentinamente ter uma violação de acesso. E se modificarmos os leitores para interceptar essa violação de acesso e reiniciarmos a operação (ou seja, não reler o endereço incorreto, calcular novamente o endereço dado o deslocamento e o novo endereço base do mremap.) Sim, eu sei que isso é mau , mas, na minha opinião, os leitores só podem ler os dados com êxito no endereço antigo ou falhar com uma violação de acesso e tentar novamente. Se for tomado cuidado suficiente, quedevemo ser seguro. Como o redimensionamento não acontecia com frequência, os leitores acabariam tendo sucesso e não ficariam presos em um loop de repetiçã

Pode ocorrer um problema se esse espaço de endereço antigo for reutilizado enquanto um leitor ainda tiver um ponteiro para ele. Portanto, não haverá violação de acesso, mas os dados estarão incorretos e o programa entrará na terra cheia de unicórnios e doces de comportamento indefinido (em que geralmente não há unicórnios nem doces.)

Mas se você controlou completamente as alocações e pôde garantir que as alocações que acontecem durante esse período nunca reutilizem esse espaço de endereço antigo, isso não deve ser um problema e o comportamento não deve ser indefinid

Estou certo? Isso poderia funcionar? Existe alguma vantagem nisso usando dois mapeamentos MAP_SHARED?

questionAnswers(1)

yourAnswerToTheQuestion