In sostanza, sto cercando di capire cosa succede quando due processi hanno lo stesso file aperto contemporaneamente e se uno potrebbe usarlo per offrire una comunicazione sicura e performante tra i due processi.
Se stai usando file normali usando read
e write
operazioni (cioè non la mappatura della memoria) allora i due processi non condividono alcuna memoria.
- Memoria dello spazio utente in Java
Buffer
gli oggetti associati al file NON sono condivisi tra gli spazi degli indirizzi. - Quando un
write
viene eseguita la chiamata di sistema, i dati vengono copiati dalle pagine in uno spazio degli indirizzi dei processi alle pagine nello spazio del kernel. (Questi potrebbero essere pagine nella cache delle pagine. Questo è specifico del sistema operativo.) - Quando un
read
viene effettuata la chiamata di sistema, i dati vengono copiati dalle pagine nello spazio del kernel alle pagine nello spazio degli indirizzi dei processi di lettura.
Deve essere fatto in questo modo. Se il sistema operativo condivide le pagine associate con il lettore e lo scrittore elabora i buffer alle loro spalle, allora si creerebbe un buco nella sicurezza/perdita di informazioni:
- Il lettore sarebbe in grado di vedere i dati nello spazio degli indirizzi di chi scrive che non erano ancora stati scritti tramite
write(...)
, e forse non lo sarebbe mai stato. - Lo scrittore sarebbe in grado di vedere i dati che il lettore (ipoteticamente) ha scritto nel suo buffer di lettura.
- Non sarebbe possibile affrontare il problema con un uso intelligente della protezione della memoria perché la granularità della protezione della memoria è una pagina contro la granularità di
read(...)
ewrite(...)
che è solo un singolo byte.
Certo:puoi tranquillamente usare la lettura e la scrittura di file per trasferire dati tra due processi. Ma dovresti definire un protocollo che consenta al lettore di sapere quanti dati ha scritto lo scrittore. E il lettore sa quando lo scrittore ha scritto qualcosa che potrebbe comportare sondaggi; per esempio. per vedere se il file è stato modificato.
Se guardi questo solo in termini di copia dei dati nel "canale" di comunicazione
-
Con i file mappati in memoria si copiano (serializzano) i dati dagli oggetti dell'heap dell'applicazione al buffer mappato e una seconda volta (deserializzano) dal buffer mappato agli oggetti dell'heap dell'applicazione.
-
Con i file ordinari ci sono due copie aggiuntive:1) dal buffer dei processi di scrittura (non mappato) alle pagine dello spazio del kernel (ad esempio nella cache delle pagine), 2) dalle pagine dello spazio del kernel al buffer dei processi di lettura (non mappato) .
L'articolo seguente spiega cosa sta succedendo con la lettura/scrittura convenzionale e la mappatura della memoria. (È nel contesto della copia di un file e della "copia zero", ma puoi ignorarlo.)
Riferimento:
- Copia zero I:Prospettiva modalità utente