2016-05-20 37 views
5

Un programma dalla risposta https://stackoverflow.com/a/1586277/6362199 utilizza la chiamata di sistema read() per ricevere esattamente 4 byte da una pipe. Si presuppone che la funzione read() restituisca -1, 0 o 4. La funzione read() restituisce 1, 2 o 3, ad esempio se è stata interrotta da un segnale?Può posix read() ricevere meno di 4 byte richiesti da una pipe?

Nella pagina man lettura (2) si trova:

In caso di successo, il numero di byte letti è restituito (zero indica fine del file), e la posizione di file è avanzata di questo numero. Il numero non è un errore se questo numero è inferiore al numero di byte richiesto; questo può accadere ad esempio perché meno byte sono attualmente disponibili (forse perché eravamo vicini a di fine file, o perché stiamo leggendo da una pipe, o da un terminale ), o perché read() è stato interrotto da un segnale.

Ciò significa che la funzione read() può essere interrotta durante la ricezione di una quantità di dati così piccola di 4 byte? Il codice sorgente di questa risposta dovrebbe essere corretto?

Nel tubo pagina man (7) si trova:

POSIX.1-2001 dice che write (2) s inferiore byte PIPE_BUF siano atomiche: i dati di uscita viene scritto al tubo come sequenza contigua.

ma non c'è nulla di simile a read().

risposta

2

Se la scrittura è atomica, ciò significa che l'intero contenuto è già presente nel buffer quando la lettura avviene, quindi l'unico modo per avere una lettura incompleta è se il thread del kernel decide di cedere prima che sia terminato - che wouldn ' t succedere qui.

In generale è possibile fare affidamento su piccoli write() s su pipe sulla stessa mappatura di sistema a identici read() s. 4 byte è indubbiamente molto più piccolo di qualsiasi altro buffer, quindi sarà sicuramente atomico.

+0

C'è un riferimento dove posso leggere che tale garanzia si verifica per read() in modo simile a write()? Qual è la dimensione massima di una lettura atomica? – pjkozlowski

+1

Non che io sappia. Lo standard POSIX http://pubs.opengroup.org/onlinepubs/9699919799/ dice riguardo a read(): "Gli sviluppatori standard consideravano l'aggiunta di requisiti di atomicità a una pipe o FIFO, ma lo riconoscevano a causa della natura di pipe e FIFOs non ci può essere alcuna garanzia di atomicità delle letture di {PIPE_BUF} o di qualsiasi altra dimensione che sarebbe un aiuto per la portabilità delle applicazioni. " –

+0

Devo chiarire che questo si applica SOLO ai socket che non bloccano (O_NONBLOCK) dal punto di vista del lettore. Se si blocca, l'unico modo per ottenere un valore non negativo minore della lunghezza di lettura è se l'altro lato ha chiuso in modo pulito la pipa e non c'erano abbastanza dati rimanenti prima di EOF (dopo tutte le scritture riuscite) per riempire la dimensione richiesta. –