Domanda

Ecco il punto: ho due applicazioni, scritte in C ++ e in esecuzione su due macchine con sistema operativo diverso (una Linux e una Windows). Uno di questi processi è responsabile dell'aggiornamento di un file XML su un NAS (Network Attached Storage) mentre l'altro legge questo file.

È possibile sincronizzare questi due processi per evitare la lettura del file mentre viene modificato?

È stato utile?

Soluzione

È possibile creare un file di blocco sul server che viene creato prima di eseguire una scrittura, attendere quindi scrivere ed eliminare al termine., Far controllare il token dal processo di lettura prima di leggere il file.

Modifica : per rispondere ai commenti, puoi implementare un modello di tipo di blocco con doppio controllo. Sia lettore che scrittore hanno un file di blocco e ricontrollare prima di lavorare, qualcosa come:

Lettore: verifica la presenza di file di blocco della scrittura, crea il file di blocco della lettura, controlla il file di blocco della scrittura, se esiste elimina il file di lettura e interrompe.

Writer: controlla il file di blocco di lettura, crea il file di blocco di scrittura, controlla il file di blocco di lettura, se esiste elimina il file di blocco di scrittura e interrompi.

Questo eviterà che i tuoi processi si calpestino a vicenda, ma potrebbe verificarsi una potenziale condizione di competizione in quanto potresti potenzialmente controllare entrambi i processi, crearli e ricontrollarli contemporaneamente, anche se ciò non causerà la lettura dei dati in uno stato incoerente ma causa l'interruzione di entrambi i processi di lettura e scrittura per il ritardo specificato

Altri suggerimenti

Grazie a tutti per le risposte.

Finalmente siamo riusciti a risolvere il nostro problema, non usando i comandi di blocco del sistema operativo (perché non eravamo sicuri che si sarebbero propagati correttamente al sistema operativo della testa del NAS), ma creando directory di blocco anziché file di blocco. La creazione della directory è un'operazione atomica e restituisce un valore di errore se la cartella esiste già. Pertanto, non è necessario verificare l'esistenza del blocco prima di acquisirlo, entrambe le operazioni vengono eseguite in un unico passaggio.

OK hai bisogno di una qualche forma di meccanismo di blocco per controllare gli accessi.

La maggior parte dei file system * nix fornisce questo. Ho il sospetto che sia disponibile anche sul file system di Windows (poiché questo meccanismo è utilizzato da Perl) ma potrebbe avere un altro nome.

Dai un'occhiata al flock ().
Questo è un meccanismo di blocco dei file. È un blocco consultivo, quindi non blocca il file e ne impedisce l'utilizzo ma fornisce un meccanismo per contrassegnare il file. Se entrambe le applicazioni utilizzano il meccanismo, è possibile controllare gli accessi al file.

flock () fornisce sia blocchi condivisi (o READ Lock) sia blocchi esclusivi (o WRITE Lock). flock bloccherà il tuo thread (in modo non occupato) fino a quando il file non sarà stato sbloccato dall'utente (fornisce anche controlli NON bloccanti in modo da poter fare altre cose durante l'attesa).

Guarda il gregge nella sezione 2 delle pagine man.

int     flock(int fd, int operation);

Flock() applies or removes an advisory lock on the file associated with the file
descriptor fd.  A lock is applied by specifying an operation parameter that is
one of LOCK_SH or LOCK_EX with the optional addition of LOCK_NB.  To unlock an
existing lock operation should be LOCK_UN.

Se i file risiedono su una condivisione NFS è possibile utilizzare fcntl (2) per bloccare il file. Controlla la domanda D10 nella FAQ su Linux NFS . Ho pochissima esperienza con le API di Windows, ma da quello che ho sentito hanno un buon supporto POSIX, quindi dovresti essere in grado di usare fcntl fintanto che supportano POSIX.1-2001.

Se si accede ai file utilizzando protocolli diversi (ad esempio AFS o SMB), è possibile configurare un server di sincronizzazione semplice che gestisca i blocchi tramite un'interfaccia IPC?

Sarebbe possibile passare da un file a un database?

Questo tipo di concordanza è qualcosa che i DBMS gestiscono molto bene. Non deve essere costoso o difficile da installare. MySql, Postgress o JavaDB gestiranno tutto questo elegantemente a costi ridotti o nulli.

In mancanza dell'opzione del database, il processo di scrittura verrebbe scritto su un "nascosto". nome file come " .updateinprogress.xml " e rinominare il file al termine dell'aggiornamento. Sulla maggior parte dei sistemi "mv" o " ren " è un'operazione atomica, quindi il processo di lettura preleva il vecchio file o il file più recente, ma non è mai stato scritto a metà.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top