¿Por qué existen open()
y close()
existen en el diseño del sistema de archivos Unix?
¿No podría el sistema operativo detectar la primera vez read()
o write()
fue llamado y hacer lo open()
que normalmente haría?
files
filesystems
architecture
api
usuario5977637
fuente
fuente
open()
existe. "¿No podría el sistema operativo detectar la primera vez read () o write () y hacer lo que normalmente haría open ()?" ¿Hay alguna sugerencia correspondiente para cuándo ocurriría el cierre ?read()
o awrite()
qué archivo acceder? Presumiblemente pasando el camino. ¿Qué sucede si la ruta del archivo cambia mientras está accediendo (entre dosread()
owrite()
llamadas)?read()
ywrite()
solo se activaopen()
.Respuestas:
Dennis Ritchie menciona en «La evolución del sistema de tiempo compartido Unix» que
open
, yclose
junto conread
,write
ycreat
estuvieron presentes en el sistema desde el principio.Supongo que un sistema sin
open
yclose
no sería inconcebible, sin embargo, creo que complicaría el diseño. En general, desea realizar múltiples llamadas de lectura y escritura, no solo una, y eso probablemente fue especialmente cierto en aquellas computadoras viejas con RAM muy limitada en la que se originó UNIX. Tener un controlador que mantenga su posición actual de archivo simplifica esto. Siread
owrite
para devolver el identificador, tendrían que devolver un par, un identificador y su propio estado de devolución. La parte de manejo del par sería inútil para todas las demás llamadas, lo que haría que ese arreglo fuera incómodo. Dejar el estado del cursor en el núcleo le permite mejorar la eficiencia no solo mediante el almacenamiento en búfer. También hay algunos costos asociados con la búsqueda de rutas: tener un identificador le permite pagarlo solo una vez. Además, algunos archivos en la visión del mundo UNIX ni siquiera tienen una ruta de acceso al sistema de archivos (o no la tenían, ahora lo hacen con cosas como/proc/self/fd
).fuente
open
/close
, estarías seguro de implementar cosas como/dev/stdout
permitir tuberías.open()
aget_inode()
e hizo que todo el sistema sea más rígida (imposible de leer / escribir el mismo archivo en varias posiciones al mismo tiempo).Entonces todas las llamadas
read
ywrite
tendrían que pasar esta información en cada operación:Si se tiene en cuenta los independientes llamadas
open
,read
,write
yclose
para ser más simple que una E / S de propósito único mensaje se basa en su filosofía de diseño. Los desarrolladores de Unix optaron por utilizar operaciones y programas simples que se pueden combinar de muchas maneras, en lugar de una sola operación (o programa) que hace todo.fuente
read
ywrite
no están restringidos a archivos que viven en un sistema de archivos, y esa es una decisión fundamental de diseño en Unix, como explica pjc50.lseek
)El concepto del identificador de archivos es importante debido a la elección de diseño de UNIX de que "todo es un archivo", incluidas las cosas que no forman parte del sistema de archivos. Como unidades de cinta, el teclado y la pantalla (¡o teletipo!), Lectores de tarjetas / cintas perforadas, conexiones en serie, conexiones de red y (la invención clave de UNIX) conexiones directas a otros programas llamados "tuberías".
Si observa muchas de las simples utilidades estándar de UNIX como
grep
, especialmente en sus versiones originales, notará que no incluyen llamadas aopen()
yclose()
sino soloread
ywrite
. El shell configura los identificadores de archivos fuera del programa y los pasa cuando se inicia. Por lo tanto, el programa no tiene que preocuparse si está escribiendo en un archivo o en otro programa.Así como
open
, las otras formas de obtener los descriptores de fichero sonsocket
,listen
,pipe
,dup
, y un mecanismo muy Heath Robinson para el envío de descriptores de archivos a través de canalizaciones: https://stackoverflow.com/questions/28003921/sending-file-descriptor-by-linux -enchufeEditar: algunas notas de clase que describen las capas de indirección y cómo esto le permite a O_APPEND trabajar con sensatez. Tenga en cuenta que mantener los datos del inodo en la memoria garantiza que el sistema no tendrá que ir a buscarlos nuevamente para la próxima operación de escritura.
fuente
creat
, ylisten
no crea un fd, pero cuando (y si) entra una solicitud mientras se escucha,accept
crea y devuelve un fd para el nuevo socket (conectado).pipe
se introdujo unos años después del inicio del desarrollo en Unix.La respuesta es no, porque open () y close () crean y destruyen un controlador, respectivamente. Hay momentos (bueno, todo el tiempo, realmente) en los que es posible que desee garantizar que es la única persona que llama con un nivel de acceso particular, ya que otra persona (por ejemplo) que escribe en un archivo que está analizando inesperadamente podría abandonar una aplicación en un estado desconocido o que conduzca a un punto muerto o un punto muerto, por ejemplo, el lema de Dining Philosophers.
Incluso sin esa consideración, hay implicaciones de rendimiento a considerar; close () permite que el sistema de archivos (si es apropiado o si lo solicitó) vacíe el búfer que estaba ocupando, una operación costosa. Varias ediciones consecutivas en un flujo en memoria son mucho más eficientes que varios ciclos de lectura-escritura-modificación esencialmente no relacionados a un sistema de archivos que, por lo que usted sabe, existe a medio mundo de distancia disperso en un centro de datos de almacenamiento masivo de alta latencia. Incluso con el almacenamiento local, la memoria suele ser muchos órdenes de magnitud más rápida que el almacenamiento masivo.
fuente
Open () ofrece una forma de bloquear archivos mientras están en uso. Si el sistema operativo abriera, leyera / escribiera y luego volviera a cerrar el sistema operativo, no habría nada que impidiera que otras aplicaciones cambien esos archivos entre operaciones.
Si bien esto puede ser manejable (muchos sistemas admiten acceso a archivos no exclusivo) por simplicidad, la mayoría de las aplicaciones asumen que los archivos que tienen abiertos no cambian.
fuente
Debido a que la ruta del archivo podría moverse mientras se supone que permanecerá igual.
fuente
Leer y escribir en un sistema de archivos puede implicar una gran variedad de esquemas de almacenamiento en búfer, mantenimiento del sistema operativo, administración de discos de bajo nivel y una gran cantidad de otras posibles acciones. Entonces, las acciones de
open()
yclose()
sirven como la configuración para este tipo de actividades bajo el capó. Las diferentes implementaciones de un sistema de archivos podrían personalizarse según sea necesario y seguir siendo transparentes para el programa de llamada.Si el sistema operativo no tenía abrir / cerrar, entonces con
read
owrite
, esas acciones de archivo aún tendrían que realizar cualquier inicialización, limpieza / gestión de búfer, etc. cada vez. Eso es una gran carga para imponer para lecturas y escrituras repetitivas.fuente
El mantra de Unix es "ofrecer una forma de hacer las cosas", lo que significa "factorizar" en piezas (reutilizables) que se combinarán a voluntad. Es decir, en este caso, separe la creación y destrucción de identificadores de archivos de su uso. Beneficios importantes llegaron más tarde, con tuberías y conexiones de red (también se manipulan a través de identificadores de archivos, pero se crean de otras maneras). Ser capaz de enviar identificadores de archivos (por ejemplo, pasarlos a procesos secundarios como "archivos abiertos" que sobreviven
exec(2)
e incluso a procesos no relacionados a través de una tubería) solo es posible de esta manera. Particularmente si desea ofrecer acceso controlado a un archivo protegido. Entonces puedes, por ejemplo, abrir/etc/passwd
para escribir y pasar eso a un proceso secundario que no tiene permitido abrir ese archivo para escribir (sí, sé que este es un ejemplo ridículo, siéntase libre de editar con algo más realista).fuente