Domanda

Scusate se chiedo di nuovo stessa domanda, ma voglio verificare!

Ho due processi P1 e P2.

P1 è uno scrittore (Produttore).
P2 è un lettore (Consumer).

C'è un po 'di memoria condivisa o un file che P1 scrive e, non appena scrive P1, P2 deve essere notificato per la lettura.

Ora, come per la mia comprensione pseudocodice per P1 dovrebbe essere

Open shared file
Create a named event("Writedone") to signal write for P2 process
Do some processing on file
Mutex.Lock()
Write to File
Mutex.Unlock()
Signal named Event.
CloseHandle on file

Ora, in P2

Open handle to Shared file
Open handle to named event
WaitForSingleEvent on named event("Writedone")
Read from file
CloseHandle on file

Domande:

  1. E 'richiesto di avere le serrature nel lettore? Il lettore appena letto il file e non cambiarlo. Quindi credo che non le serrature sono tenuti nel lettore. Pensieri? Può andare male in qualche caso senza serrature?
  2. Sto aprendo e chiudendo le maniglie per il file ogni volta che durante la lettura e la scrittura. Penso che non è necessaria. Posso aprire l'handle di file nel costruttore e chiuderlo nel distruttore di lettore e scrittore. Ma posso leggere dal file quando viene utilizzato per iscritto?

EDIT:. Ogni volta che scrittore è scrivere 10 byte alla fine del file e il lettore dovrebbe leggere gli ultimi 10 byte scritti dallo scrittore

È stato utile?

Soluzione

La risposta è: bloccaggio è necessaria se (e solo se) entrambi i fili possono utilizzare le stesse risorse condivise contemporaneamente. Non c'è abbastanza informazioni sulla vostra specifica implementazione, ma ho alcune osservazioni:

  1. Blocco solo durante la scrittura non ha senso. Aggiunge solo alcuni sovraccarico, ma non impedisce qualsiasi accesso concorrente finché il lettore è inoltre bloccata correttamente.
  2. Chiusura sarebbe necessario se le operazioni di file che modificano strutture connesse con descrittori del file non sono sincronizzati in alcun modo. Può accadere che P1 potrebbe iniziare a scrivere per il file quando P2 è ancora leggendo. Se le operazioni di lettura e scrittura modificano le stesse strutture del sistema, senza alcuna sincronizzazione sottostante si finirà con dati danneggiati. E 'difficile dire se questo è il caso qui perché lei non ha citato che (librerie) funzione particolare è stato utilizzato. operazioni sui file vengono sincronizzati sulla maggior parte dei sistemi, quindi non dovrebbe essere un problema.
  3. Da quello che hai scritto su "10 byte porzioni di informazioni", il blocco esplicito non sembra essere necessario (a meno 2 # non impone di esso). P1 produce quantum dei dati. Quando i dati sono pronti per essere letto P1 P2 comunica a tale proposito (dall'evento; passaggio evento deve essere sincronizzato internamente, comunque). P2 sa che potrebbe leggere quantum dei dati e quindi ha bisogno di attendere per la successiva notifica. Può accadere che la successiva notifica sarebbe stata inviata prima di quella precedente viene gestito. Così, gli eventi deve essere in coda in qualche modo. È inoltre possibile utilizzare il semaforo, invece di notifica eventi.

Altri suggerimenti

È necessario che il lettore per ottenere un blocco - l'utilizzo di eventi non è un sostituto. Senza di esso, uno scrittore potrebbe iniziare a scrivere in qualsiasi punto del codice lettore.

È assolutamente necessario il consumatore per bloccare in modo da evitare che il produttore dal aggiungendo al file prima che il lettore può leggere. Immaginate questo scenario:

Producer writes and signals
Consumer receives signal
Consumer opens the file
Producer fires again and writes another 10 bytes
Producer signals
Consumer reads the last 10 bytes
Consumer closes the file

Quello che succede dopo dipende se l'evento denominato è reset manuale o ripristino automatico. Se si tratta di reset automatico, quindi il consumatore vedrà il secondo segnale, e tornare indietro e leggere di nuovo la stessa cosa. Se si tratta di riarmo manuale, quindi il consumatore sta per resettare l'evento e perdere l'ultima cosa che il produttore ha scritto.

Si noti che anche con la serratura si dispone di una condizione di competizione se il produttore può rispondere abbastanza velocemente. Cioè, il produttore potrebbe essere in grado di mettere un secondo record nel file prima che il consumatore sia in grado di leggere il primo.

Sembra che quello che hai qui è una coda FIFO implementato in un file, e sei a seconda la capacità del consumatore di elaborare i dati più velocemente di quanto il produttore può crearla. Se si riesce a garanzia che il comportamento, allora sei a posto. In caso contrario, il consumatore dovrà tenere traccia di dove l'ultima legge in modo da sapere dove si dovrebbe leggere successiva.

  1. Si ha bisogno di bloccare il mutex nel lettore, se lo scrittore può iniziare a scrivere in qualsiasi momento. Assicurarsi che il mutex è un nome così P2 possibile aprirlo.

  2. Se si apre il file con FileShare.ReadWrite in entrambi i processi, è possibile lasciarla aperta.

    |

nel lettore, si può avere a cercare nel luogo si colpisce EOF prima di poter leggere di nuovo.

Se si è sicuri che lo scrittore sta sempre aggiungendo e si può dire dove un record di estremità (perché sono sempre 10 byte per esempio), e si può accettare un piccolo ritardo, e lo scrittore scrive sempre un registro completo, si può fare questo senza mutex ed eventi a tutti. Aprire il file con FileShare.ReadWrite, e nel lettore, tenere cercando nello stesso posto e cercando di leggere il tuo record e dormire per un secondo se non poteva. Se si riesce a leggere un intero disco, hai uno. Capire la vostra posizione e ciclo di nuovo a cercare di quel luogo e provare a leggere di nuovo. Questa è una specie di come tail -f lavora a Unix.

Oltre alle normali funzioni di sincronizzazione, è possibile utilizzare il API cambiamento fascicolo di notifica su Windows per attendere le modifiche del file.

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