Di solito sono coinvolti due livelli di buffering:
- Buffer interni
- Buffer del sistema operativo
I buffer interni sono buffer creati dal runtime / libreria / linguaggio su cui si sta programmando ed è pensato per accelerare le cose evitando chiamate di sistema per ogni scrittura. Invece, quando si scrive su un oggetto file, si scrive nel relativo buffer e ogni volta che il buffer si riempie, i dati vengono scritti nel file effettivo utilizzando le chiamate di sistema.
Tuttavia, a causa dei buffer del sistema operativo, ciò potrebbe non significare che i dati vengono scritti sul disco . Può semplicemente significare che i dati vengono copiati dai buffer gestiti dal runtime nei buffer gestiti dal sistema operativo.
Se si scrive qualcosa e finisce nel buffer (solo) e l'alimentazione viene interrotta sul computer, i dati non si trovano sul disco quando il computer si spegne.
Quindi, per aiutarvi con ciò avete i metodi flush
e fsync
, sui loro rispettivi oggetti.
Il primo flush
scriverà semplicemente tutti i dati che si trovano in un buffer di programma nel file effettivo. In genere ciò significa che i dati verranno copiati dal buffer del programma al buffer del sistema operativo.
In particolare, ciò significa che se un altro processo ha lo stesso file aperto per la lettura, sarà in grado di accedere ai dati appena scaricati nel file. Tuttavia, ciò non significa necessariamente che sia stato "permanentemente" archiviato su disco.
Per fare ciò, è necessario chiamare il os.fsync
metodo che garantisce che tutti i buffer del sistema operativo siano sincronizzati con i dispositivi di archiviazione per cui sono, in altre parole, quel metodo copierà i dati dai buffer del sistema operativo sul disco.
In genere non è necessario preoccuparsi di entrambi i metodi, ma se ci si trova in uno scenario in cui la paranoia su ciò che effettivamente finisce sul disco è una buona cosa, è necessario effettuare entrambe le chiamate secondo le istruzioni.
Addendum nel 2018.
Si noti che i dischi con meccanismi cache sono ora molto più comuni rispetto al 2013, quindi ora ci sono ancora più livelli di cache e buffer coinvolti. Mi assumo questi buffer saranno trattati dai richiami di sincronizzazione / a filo pure, ma io non lo so davvero.
with file('blah') as fd: #dostuff
costrutto, so che garantisce la chiusura del descrittore di file. Svuota o sincronizza anche?