2009-12-27 17 views
13

Es obvio que, en general, la llamada al sistema de lectura (2) puede devolver menos bytes de lo que se pidió que se leyera. Sin embargo, bastantes programas asumen que al trabajar con archivos locales, leer (2) nunca devuelve menos de lo que se solicitó (a menos que el archivo sea más corto, por supuesto)."lectura corta" del sistema de archivos, ¿cuándo puede suceder?

Entonces, mi pregunta es: ¿en Linux, en qué casos puede leer (2) devolver menos de lo que se solicitó si lee un archivo abierto y no se encuentra EOF y la cantidad que se lee es de unos pocos kilobytes como máximo?

Algunas conjeturas:

  • puede recibió señales de interrumpir una lectura de esa manera, pero no hacer que falle?
  • ¿Pueden los diferentes sistemas de archivos afectar a este comportamiento? ¿Hay algo especial sobre jffs2?
+0

¿Qué programas "asumen que al trabajar con archivos locales, leer (2) nunca devuelve menos de lo que se solicitó"? En el caso general, eso suena como un error. – Ken

+0

Por ejemplo, fstype binary in klibc utils. Parece que muchos programas de bajo nivel que pueden suponer que están trabajando con archivos suponen directamente que las lecturas nunca son cortas. – Nakedible

Respuesta

13

POSIX.1-2008 states:

El valor devuelto puede ser inferior a nbyte si el número de bytes que quedan en el archivo es menor que nbyte, si la solicitud lectura() era interrumpido por una señal , o si el archivo es una tubería o FIFO o archivo especial y tiene menos que nbyte bytes inmediata ly disponible para leer.

sistemas de archivos basados ​​en disco utilizan generalmente ininterrumpida lee, lo que significa que el operación de lectura en general, no puede ser interrumpido por una señal. Los sistemas de archivos basados ​​en red a veces usan lecturas interrumpibles, que pueden devolver datos parciales o sin datos. (En el caso de NFS esto se puede configurar utilizando la opción de montaje intr). A veces también implementan tiempos de espera.

Tenga en cuenta que incluso/some/arbitrary/file/path puede referirse a un archivo especial FIFO o , por lo que lo que usted pensó que era un archivo normal puede no serlo.Por lo tanto, es una buena práctica para manejar lecturas parciales aunque sean poco probables.

+1

Gracias. Si esto es correcto, entonces tenemos algo más de depuración que hacer. Estamos obteniendo una lectura breve confirmada en un sistema de archivos jffs2 (que no debería tener lecturas interrumpibles, supongo), y el archivo es definitivamente un archivo normal. La situación ocurre a lo sumo una vez al año, por lo que la reproducibilidad es baja. – Nakedible

+1

El sistema de archivos está _adorado_ para interrumpir la lectura después de leer un bloque. – Joshua

1

Una señal recibida solo hace que read() falle si aún no ha leído un solo byte. De lo contrario, devolverá datos parciales.

Y creo que los sistemas de archivos alternativos pueden devolver lecturas cortas en otras situaciones. Por ejemplo, tiene sentido (para mí) tener un sistema de archivos basado en red que se comporte como un conector de red wrt lecturas cortas (= tenerlas a menudo).

+0

¡Gracias, esto fue útil! Aunque la información sobre sistemas de archivos interrumpibles e ininterrumpibles fue aún más útil. – Nakedible

3

Tengo que preguntar: "¿por qué te importa el motivo"? Si la lectura puede devolver una cantidad de bytes menor que la cantidad solicitada (que, como usted señala, ciertamente puede hacerlo), ¿por qué no desea tratar con esa situación?

+0

Para agregar, usted va a verificar los datos de todos modos, por lo tanto, si es corto, lo sabrá de inmediato. De lo contrario, ¿qué otra razón hay para leer? –

+9

Neil, tengo que preguntar: ¿por qué te importa por qué quiere saber cómo puede pasar esto? Incluso si se enfrenta a esta situación, sigue siendo muy útil saber cómo puede suceder, p. para que pueda probarlo y probar que su código lo maneje como se espera. Y si no es su código personal el que no está manejando este caso, esta información sería necesaria como parte de las instrucciones para reproducir el problema que debe acompañar a cualquier informe de error o envío de parches. – mark4o

+0

La razón por la que estoy preguntando es que estamos viendo este comportamiento en una base instalada de miles de sistemas y necesitamos evaluar con la mayor precisión posible qué tan común es probable que este problema sea a largo plazo. Comprender cómo o por qué ocurre es parte de la investigación. – Nakedible

1

Si realmente es un archivo que está leyendo, puede leer brevemente como la última lectura antes de finalizar el archivo.

Sin embargo, en general es mejor comportarse como si CUALQUIER lectura pudiera ser una breve lectura. Si lo que está leyendo es una tubería o un dispositivo de entrada (stdin) en lugar de un archivo, puede obtener una breve lectura siempre que su memoria intermedia sea más grande que la que está actualmente en el búfer de entrada.

+0

Lo que quise decir con no encontrar EOF es exactamente que no es la última lectura antes del final del archivo. Además, el archivo en cuestión es un archivo normal. – Nakedible

0

No estoy seguro, pero esta situación podría surgir cuando el sistema operativo se está quedando sin páginas en la memoria caché de la página. Podría sugerir que se invocará el hilo de descarga en ese caso, pero depende de la heurística utilizada en el programador de E/S. Esta situación podría provocar que una lectura devuelva menos bytes.

Cuestiones relacionadas