Considere: dois processos podem ter o mesmo arquivo aberto para leitura & escrevendo ao mesmo tempo, então algum tipo de comunicação é possível entre os dois.
Quando o processo A grava no arquivo, ele primeiro preenche um buffer dentro de sua própria memória específica do processo com alguns dados, então chama write
que copia esse buffer para outro buffer de propriedade do kernel (na prática, isso será uma entrada de cache de página, que o kernel marcará como suja e, eventualmente, gravará de volta no disco).
Agora processe B leituras do mesmo ponto no mesmo arquivo; read
copia os dados do mesmo local no cache da página, em um buffer na memória de B.
Observe que são necessárias duas cópias: primeiro os dados são copiados de A para a memória "compartilhada" e, em seguida, copiados novamente da memória "compartilhada" para B.
A poderia usar mmap
para disponibilizar a memória cache da página diretamente em seu próprio espaço de endereçamento. Agora, ele pode formatar seus dados diretamente na mesma memória "compartilhada", em vez de preencher um buffer intermediário e evitar uma cópia.
Da mesma forma, B poderia mmap
da página diretamente em seu espaço de endereço. Agora ele pode acessar diretamente o que quer que seja colocado na memória "compartilhada", novamente sem ter que copiá-lo em um buffer separado.
(Obviamente, algum tipo de sincronização é necessário se você realmente quiser usar este esquema para o IPC, mas isso está fora do escopo).
Agora, considere o caso em que A é substituído pelo driver para qualquer dispositivo no qual este arquivo está armazenado. Ao acessar o arquivo com mmap
, o B ainda evita uma cópia redundante (o DMA ou qualquer outro no cache da página é inevitável, mas não precisa ser copiado novamente no buffer de B).
Existem também algumas desvantagens, é claro. Por exemplo:
-
se o seu dispositivo e sistema operacional suportarem I / O de arquivo assíncrono, você pode evitar o bloqueio de leituras / gravações usando isso ... mas ler ou gravar uma página mmapped pode causar uma falha de página de bloqueio que você não pode manipular diretamente (embora você possa tentar evitá-lo usando
mincore
etc.) -
ele não impedirá que você tente ler o final de um arquivo ou ajudá-lo a anexá-lo de uma maneira interessante (você precisa verificar o comprimento ou explicitamente
truncate
do arquivo maior)