2012-04-05 8 views
12

Situazione:Quali condizioni determinano l'apertura di una pipe denominata non bloccante (fifo) "non disponibile" per le letture?

new_pipe = os.open(pipe_path, os.O_RDONLY | os.O_NONBLOCK) # pipe_path points to a FIFO 
data = os.read(new_pipe, 1024) 

La lettura solleva di tanto in tanto errno -11: Risorsa temporaneamente non disponibile.

Quando viene generato questo errore? Sembra molto raro, poiché i casi comuni restituiscono i dati:

  • Se nessuno scrittore ha la pipe aperta, viene restituito lo str vuoto ('').
  • Se lo scrittore ha il tubo aperto, ma non vi sono dati nel FIFO, vuota str ('') è anche tornato
  • E, naturalmente, se lo scrittore mette i dati nel FIFO, che i dati verranno letti.
+0

possibile duplicato di [sendto: Risorsa temporaneamente non disponibile (errno 11)] (http://stackoverflow.com/questions/5737493/ sendto-resource-temporary-unavailable-errno-11) – agf

+0

@agf: l'altra domanda riguarda un errore sendto, che si verifica perché il buffer di invio è pieno. La connessione a questa particolare domanda è discutibile nella migliore delle ipotesi, visto che stiamo parlando di leggere i pipe Unix qui –

+0

@NiklasB. La domanda certamente non è simile, ma la risposta è. Il voto di chiudere come duplicato era solo un modo conveniente per collegarsi all'altra domanda. e collegalo nella parte superiore della barra laterale. – agf

risposta

11

Dalla POSIX specification of the read system call (sottolineatura mia):

Quando si tenta di leggere da un tubo vuoto o FIFO:

  • Se nessun processo ha il tubo aperto in scrittura, lettura () deve restituire 0 a indicare la fine del file.

  • Se qualche processo ha il tubo aperto per la scrittura e O_NONBLOCK è impostato, read() restituisce -1 e imposta errno a [EAGAIN].

Quindi, in pratica il secondo presupposto è sbagliato:

Se lo scrittore ha il tubo aperto, ma non vi sono dati nel FIFO, str vuota ('') è anche tornato

Questo sarebbe contro la specifica e non posso riprodurre tale comportamento sulla mia macchina (solleva EAGAIN per me). Questo non è un grosso problema, tuttavia, si può solo intercettare l'eccezione e riprovare:

import errno 

def safe_read(fd, size=1024): 
    ''' reads data from a pipe and returns `None` on EAGAIN ''' 
    try: 
     return os.read(fd, size) 
    except OSError, exc: 
     if exc.errno == errno.EAGAIN: 
     return None 
     raise 
+0

Grazie mille. Sembra che io abbia effettivamente degli errori nel mio codice di test! – UsAaR33