-
Uno dei motivi potrebbe essere che hai un codice (legacy) impostato per scrivere in un buffer di dati, e quindi questo buffer viene scritto nel file in una volta sola alla fine. In questo caso usando
mmap
salverà almeno una copia dei dati, poiché il sistema operativo può scrivere direttamente il buffer su disco. Finché si tratta solo della scrittura di file, non riesco (ancora) a immaginare altri motivi per cui vorresti utilizzaremmap
. -
No, la protezione non è rilevante qui direi.
-
Potrebbe salvare una o due copie dei dati ad es. buffer dell'app al buffer libc al buffer del sistema operativo, vedi punto 1. Questo potrebbe fare una differenza di prestazioni durante la scrittura di grandi quantità di dati.
-
No. Per quanto ne so, il sistema operativo è libero di scrivere i dati in qualsiasi momento, purché i dati siano stati scritti su disco dopo una chiamata a
msync
omunmap
su quella regione di memoria. (E per la maggior parte dei file probabilmente non scriverà nulla tra la maggior parte del tempo, per motivi di prestazioni:scrivere un intero blocco su disco perché un byte è cambiato è piuttosto costoso, in particolare se c'è da aspettarselo che molte altre modifiche al blocco verranno apportate nel prossimo futuro.)
Un file mappato in memoria è in realtà parzialmente o interamente mappato in memoria (RAM), mentre un file su cui scrivi verrebbe scritto in memoria e quindi scaricato su disco. Un file mappato in memoria viene prelevato dal disco e inserito in memoria in modo esplicito per la lettura e/o la scrittura. Rimane lì finché non lo annulli dalla mappatura.
L'accesso al disco è più lento, quindi quando hai scritto su un file, questo verrà scaricato sul disco e non risiederà più nella RAM, il che significa che la prossima volta che avrai bisogno del file, potresti ottenerlo dal disco ( lento), mentre nei file mappati in memoria, sai che il file è nella RAM e puoi accedervi più velocemente rispetto a quando è su disco.
Inoltre, i file mappati in memoria vengono spesso utilizzati come meccanismo IPC, quindi due o più processi possono facilmente condividere lo stesso file e leggere/scrivere su di esso. (utilizzando i necessari meccanismi di sincronizzazione)
Quando è necessario leggere spesso un file e questo file è piuttosto grande, può essere vantaggioso mapparlo nella memoria in modo da avere un accesso più rapido ad esso piuttosto che doverlo aprire e scaricarlo dal disco ogni volta.
MODIFICA:
Questo dipende sulle tue esigenze, quando hai un file a cui sarà necessario accedere molto frequentemente da thread diversi, quindi non sono sicuro che la mappatura della memoria del file sarà necessariamente una buona idea, dal momento che dovrai sincronizzare accedere a questo file mmap'ed se lo si desidera scrivere su di esso, negli stessi posti da thread diversi. Se ciò accade molto spesso, potrebbe essere un punto per la contesa delle risorse.
Solo leggendo dal file, questa potrebbe essere una buona soluzione, perché non hai davvero bisogno di sincronizzare l'accesso, se sei solo leggendo da esso da più thread. Nel momento in cui inizi a scrivere, devi farlo utilizzare meccanismi di sincronizzazione.
Suggerisco di fare in modo che ogni thread esegua il proprio accesso ai file in un thread locale, se devi scrivere sul file, proprio come fai con qualsiasi altro file. In questo modo riduce la necessità di sincronizzazione dei thread e la probabilità di bug difficili da trovare e correggere.
1) Hai frainteso la chiamata di sistema write(2). write() non scrive, copia semplicemente un contenuto del buffer nella catena del buffer del sistema operativo e lo contrassegna come sporco. Uno dei thread del sistema operativo (bdflush IIRC) raccoglierà questi buffer, li scriverà su disco e giocherà con alcuni flag. più tardi. Con mmap, accedi direttamente al buffer del sistema operativo (ma se ne modifichi il contenuto, anche questo verrà contrassegnato come sporco)
2) Non si tratta di protezione, si tratta di impostare flag nelle voci della tabella delle pagine.
3) si evita il doppio buffering. Inoltre puoi indirizzare il file in termini di caratteri invece che di blocchi, il che a volte è più pratico
4) Sono i buffer di sistema (collegati al tuo spazio degli indirizzi) che hai utilizzato. Il sistema potrebbe aver scritto o meno parti di esso su disco.
5) Se i thread appartengono allo stesso processo e condividono le pagetable e lo spazio degli indirizzi, sì.