Quali sono le garanzie per le scritture simultanee in una pipe denominata?


32

Ad esempio, ho creato una pipe denominata come la seguente:

mknod myPipe p

E ne ho letto da qualche processo (ad esempio un server). Ad esempio, ho usato tail:

tail -f myPipe

Se diversi processi client scrivono alcuni messaggi al suo interno (ad esempio, echo "msg" >> myPipec'è qualche possibilità che i messaggi vengano interfogliati, in questo modo:

 <beginning of message1><message2><ending of message1>

O il processo di scrittura su named pipe è atomico?

Risposte:


29

Dipende da quanto ogni processo sta scrivendo (supponendo che il tuo sistema operativo sia conforme a POSIX al riguardo). Da write():

Le richieste di scrittura su una pipe o FIFO devono essere gestite come un normale file con le seguenti eccezioni:
[...]

  • Le richieste di scrittura di {PIPE_BUF} byte o meno non devono essere intercalate con i dati di altri processi che eseguono scritture sulla stessa pipe. Scritture superiori a {PIPE_BUF} byte possono avere dati intercalati, su confini arbitrari, con scritture di altri processi, indipendentemente dal fatto che sia impostato il flag O_NONBLOCK dei flag di stato del file.

Anche nella sezione Razionale relativa a tubi e FIFO:

  • Atomico / non atomico : una scrittura è atomica se l'intero importo scritto in un'operazione non è intercalato con i dati di altri processi. Ciò è utile quando ci sono più autori che inviano dati a un singolo lettore. Le applicazioni devono sapere quanto ci si può aspettare che una richiesta di scrittura venga eseguita atomicamente. Questo massimo si chiama {PIPE_BUF}. Questo volume di POSIX.1-2008 non indica se le richieste di scrittura per più di {PIPE_BUF} byte sono atomiche, ma richiede che le scritture di {PIPE_BUF} o meno byte siano atomiche.

Il valore if PIPE_BUFè definito da ogni implementazione, ma il minimo è 512 byte (vedi limits.h). Su Linux, sono 4096 byte (vedi pipe(7)).


5
A proposito, PIPE_BUF è garantito per essere almeno 512. Nota che devi anche garantire che il tuo processo scriva effettivamente ogni linea su di esso in una singola chiamata di scrittura. L'abilitazione del buffering di linea ( setvbuf(stdout, NULL, _IOLBF,512)) lo farà senza richiedere l'utilizzo di funzioni di basso livello.
Casuale 832

Ecco una tabella di PIPE_BUFvalori osservati su sistemi Unix comuni: ar.to/notes/posix#pipe-buf
Arto Bendiken,

Non capisco come i socket possano essere multiplexati ... ma i pipe con nome non possono ?? tutto su unix è solo un file giusto? lulz
Alexander Mills

@AlexanderMills: non capisco il tuo commento
Mat

1
@AlexanderMills: no, questo è il valore minimo
Mat
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.