2011-12-14 12 views
12

Aquí hay una pregunta muy básica que tengo. En la diapositiva de conferencias de mi profesor, hay un ejemplo que realmente no entiendo.E/S estándar C básicos de E/S UNIX

Ella escribió:

printf("u"); 
write(STDOUT_FILENO, "m", 1); 
printf("d\n"); 

... y ella dijo que el puesto fuera de este código sería:

barro

Yo no lo entiendo. Entonces, si alguien entiende por qué sucede esto, por favor explíqueme. (. En la segunda página de la última diapositiva):

referencia a esta pregunta

http://lagoon.cs.umd.edu/216/Lectures/lect17.pdf 

Respuesta

20

write es una llamada al sistema implementada por la interfaz entre el modo de usuario (donde se ejecutan programas como el suyo) y el núcleo del sistema operativo (que maneja la escritura real en el disco cuando los bytes se escriben en un archivo).

printf es una función de biblioteca estándar C - se implementa mediante el código de biblioteca cargado en su programa de modo de usuario.

Las funciones de salida de la biblioteca estándar C amortiguan su salida, por defecto hasta que se alcanza el final de línea. Cuando el búfer está lleno o finalizado con una nueva línea, se escribe en el archivo mediante una llamada al write desde la implementación de la biblioteca.

Por lo tanto, la salida a través de printf no se envía al sistema operativo write inmediatamente. En su ejemplo, memoriza la letra 'u', luego escribe inmediatamente la letra 'm', luego agrega "d \ n" al búfer y la biblioteca estándar realiza la llamada write(STDOUT_FILENO, "ud\n");

+0

+1 para una explicación detallada. – hari

+0

¡Lo tengo, gracias! –

10

Por defecto, stdout es alineación tamponada; no se vacía a la salida hasta que encuentra un carácter de nueva línea (o hasta que se llene el búfer).

Por lo tanto, el "u" se encuentra en el búfer hasta que se reciba el "d\n". Pero el write puentea este búfer.

+0

No diría que escribir "subvierte" " cualquier cosa. El buffer está intacto y funciona correctamente. Más exactamente, escribir es una llamada al sistema y printf es una función de biblioteca. –

+0

@Heath: "pasa por alto", entonces! –

+2

stdout es la línea * no * almacenada de manera predeterminada. * si * stdout está asociado con un tty, entonces es buffer de línea por defecto. Si stdout es un archivo regular o un conducto (o realmente cualquier cosa que no sea un tty), será bloqueado por defecto. –

Cuestiones relacionadas