¿Cuáles son las garantías para escrituras concurrentes en una tubería con nombre?


32

Por ejemplo, creé una tubería con nombre como la siguiente:

mknod myPipe p

Y leí de algún proceso (por ejemplo, algún servidor). Por ejemplo, utilicé tail:

tail -f myPipe

Si varios procesos del cliente escriben algunos mensajes en él (por ejemplo echo "msg" >> myPipe, ¿hay alguna posibilidad de que los mensajes se intercalen, como este:

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

¿O el proceso de escribir en una tubería con nombre es atómico?

Respuestas:


29

Depende de cuánto esté escribiendo cada proceso (suponiendo que su sistema operativo sea compatible con POSIX a este respecto). De write():

Las solicitudes de escritura a una tubería o FIFO se manejarán de la misma manera que un archivo normal con las siguientes excepciones:
[...]

  • Las solicitudes de escritura de {PIPE_BUF} bytes o menos no se intercalarán con datos de otros procesos que realizan escrituras en la misma tubería. Las escrituras de más de {PIPE_BUF} bytes pueden tener datos intercalados, en límites arbitrarios, con escrituras de otros procesos, ya sea que se establezca o no el indicador O_NONBLOCK de los indicadores de estado del archivo.

También en la sección Justificación de tuberías y FIFO:

  • Atómico / no atómico : una escritura es atómica si la cantidad total escrita en una operación no se intercala con datos de ningún otro proceso. Esto es útil cuando hay múltiples escritores que envían datos a un solo lector. Las aplicaciones necesitan saber qué tan grande se puede esperar que una solicitud de escritura se realice atómicamente. Este máximo se llama {PIPE_BUF}. Este volumen de POSIX.1-2008 no dice si las solicitudes de escritura de más de {PIPE_BUF} bytes son atómicas, pero requiere que las escrituras de {PIPE_BUF} o menos bytes sean atómicas.

El valor if PIPE_BUFestá definido por cada implementación, pero el mínimo es de 512 bytes (ver limits.h). En Linux, son 4096 bytes (ver pipe(7)).


55
PIPE_BUF, por cierto, tiene una garantía de al menos 512. Tenga en cuenta que también debe garantizar que su proceso realmente escriba cada línea en una sola llamada de escritura. Habilitar el almacenamiento en línea ( setvbuf(stdout, NULL, _IOLBF,512)) hará esto sin requerir que use funciones de bajo nivel.
Random832

Aquí hay una tabla de PIPE_BUFvalores observados en sistemas Unix comunes: ar.to/notes/posix#pipe-buf
Arto Bendiken

No entiendo cómo se pueden multiplexar los enchufes ... pero las tuberías con nombre no pueden? todo en Unix es solo un archivo, ¿verdad? lulz
Alexander Mills

@AlexanderMills: No entiendo tu comentario
Mat

1
@AlexanderMills: no, ese es el valor mínimo
Mat
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.