Domanda

Ho questo strumento in cui un singolo file di log-come viene scritto da diversi processi.

Quello che voglio ottenere è quello di avere il file troncato quando viene prima apertura, e poi tutte le scritture fatte alla fine dai numerosi processi che hanno aperto. Tutte le scritture sono sistematicamente lavati e mutex protetti in modo che non ottengo uscita confuso.

In primo luogo, un processo crea il file, poi inizia una sequenza di altri processi, uno alla volta, che quindi aprire il file e scrivere ad esso (il maestro a volte interviene con contenuti aggiuntivi, il processo di schiavi può o non può essere aperti e scrivere qualcosa).

Mi piacerebbe, per quanto possibile, di non utilizzare più IPC che ciò che esiste già (tutto quello che sto facendo ora sta scrivendo un tubo popen-generato). Non ho accesso a librerie esterne altri che l'API CRT e Win32, e vorrei non iniziare a scrivere codice di serializzazione.

Ecco un codice che mostra dove ho passato:

// open the file. Truncate it if we're the 'master', append to it if we're a 'slave'
std::ofstream blah(filename, ios::out | (isClient ? ios:app : 0));

// do stuff...

// write stuff
myMutex.acquire();
blah << "stuff to write" << std::flush;
myMutex.release();

Bene, questo non funziona: anche se l'output del processo slave è ordinato come previsto, ciò che il maestro scrive è o raggruppato insieme o al posto sbagliato, quando esiste a tutti

.

Ho due domande: è la combinazione di bandiera dato al costruttore della ofstream quella giusta? Sto andando nel modo giusto comunque?

È stato utile?

Soluzione 2

Come suggerito da Reinier, il problema non era nel mio modo di utilizzare i file, ma nel modo in cui i programmi si comportano.

I fstreams fare bene.

Quello che ho perso fuori è la sincronizzazione tra il master e slave (ex assumeva una particolare operazione era sincronismo dove non era).

modifica: Oh, bene, c'è ancora stato un problema con le bandiere aperte. Il processo che ha aperto il file con ios :: out non spostare il puntatore del file come necessari (testo cancellando altri processi scrivevano), e l'utilizzo di seekp () completamente avvitato l'uscita durante la scrittura a cout come un'altra parte del codice utilizza cerr.

La mia soluzione finale è quello di mantenere il mutex e il colore, e, per il processo principale, aprire il file in ios :: out modalità (per creare o troncare il file), chiuderlo e riaprirlo con ios :: app .

Altri suggerimenti

Se sarete scrivendo un sacco di dati per il registro da più thread, è necessario ripensare il progetto, dal momento che tutte le discussioni bloccheranno sul tentativo di acquisire il mutex, e in generale non si desidera che il le discussioni bloccate dal lavoro facendo in modo che possano accedere. In tal caso, che ci si vuole scrivere il thread di lavoro per registrare le voci di coda (che richiede solo spostando i dati in memoria), e hanno un thread dedicato per tirare le voci dalla coda e scriverle in uscita. In questo modo i vostri thread di lavoro sono bloccati per il più breve tempo possibile.

Si può fare anche meglio di questo utilizzando async I / O, ma che diventa un po 'più complicato.

ho fatto un 'sistema di registro lil che ha il proprio processo e consente di gestire il processo di scrittura, l'idea è abbastanza simeple. Le proccesses che utilizza i registri semplicemente inviare a una coda in attesa che il processo di log tenterà di scrivere in un file. E 'come procesing lotto in qualsiasi applicazione di rendering in tempo reale. In questo modo avrete GRT liberarsi di stretti operazioni troppo aperti / file. Se posso io aggiungere il codice di esempio.

Come si fa a fare una mutex?
Per far funzionare tutto questo questo deve essere un mutex denominato in modo che entrambi i processi in realtà bloccano sulla stessa cosa.
È possibile verificare che il mutex è in realtà funziona correttamente con un piccolo pezzo di codice che bloccarla in un processo e un altro processo che cerca di ottenerlo.

Suggerisco blocco in modo tale che il testo è completamente scritto nel file prima di rilasciare il mutex. Ho avuto casi in cui il testo da un compito è interrotta da un testo da un thread a priorità più elevata; non sembra molto carina.

Inoltre, mettere il formato in formato separati da virgola, o qualche formato che può essere caricato facilmente in un foglio elettronico. Includere ID filo e timestamp. L'intreccio delle linee di testo mostra come i filetti interagiscono. Il parametro ID consente di ordinare dal thread. Timestamp possono essere utilizzati per mostrare accesso sequenziale così come la durata. Scrivendo in un formato amichevole foglio di calcolo vi permetterà di analizzare il file di log con uno strumento esterno senza scrivere alcun utilità di conversione. Questo mi ha aiutato molto.

Una possibilità è quella di utilizzare ACE :: registrazione. Ha una efficace attuazione del disboscamento concorrente.

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