Descriptores de archivo en la programación del servidor

  
        Todos los archivos en el sistema Linux están protegidos por el mecanismo del sistema de archivos virtual (VFS). Los usuarios pueden implementar operaciones en diferentes controladores a través de una interfaz unificada. Para cada archivo, se necesita una referencia para indicar la descripción del archivo. El archivo de la aplicación es similar al identificador de las viudas. La mayoría de las operaciones en el archivo están a cargo de este descriptor, como lectura, escritura. Para cada descriptor de archivo, el núcleo se gestiona utilizando tres estructuras de datos.

(1) Cada proceso tiene un registro en la tabla de procesos, y cada registro tiene una tabla de descriptores de archivos abiertos, que se puede considerar como un vector, y cada descriptor ocupa un elemento. Asociado con cada descriptor de archivo está:

(a) Marca de descriptor de archivo.
(actualmente solo se define un indicador de descriptor de archivo FD_CLOEXEC)

(b) Puntero a una entrada de la tabla de archivos.

(2) El kernel mantiene una tabla de archivos para todos los archivos abiertos. Cada entrada de archivo contiene:

(a) Indicadores de estado del archivo (leer, escribir, agregar, sincronizar, no bloquear, etc.).

(b) El desplazamiento del archivo actual.
(es decir, el valor operado por la función lseek)

(c) Puntero a la entrada v-node del archivo.

(3) Cada archivo abierto (o dispositivo) tiene una estructura de v-nodos. El v-nodo contiene información de puntero para tipos de archivos y funciones que realizan varias operaciones en este archivo. Para la mayoría de los archivos, el nodo v también contiene el i-nodo (inodo) del archivo. Esta información se lee en la memoria del disco cuando se abre el archivo, por lo que toda la información sobre el archivo está disponible rápidamente. Por ejemplo, el i-node contiene el propietario del archivo, la longitud del archivo, el dispositivo donde se encuentra el archivo, un puntero al bloque de datos real utilizado por el archivo en el disco, etc.

Después de que el sistema descrito anteriormente de tres paquete de archivos, cada uno responsable de funciones diferentes, de arriba a abajo una primera capa para identificar el archivo, los datos independientes para el segundo proceso de gestión de capa, el sistema de archivos gerente tercera capa Metadatos, directamente asociados con un archivo. Una ventaja de esta idea en capas es que la capa superior puede reutilizar la estructura de la capa inferior. Puede haber varias entradas de descriptores de archivos que apunten a la misma entrada de la tabla de archivos, o varias entradas de archivos que apunten al mismo nodo V.

Si dos procesos separados abren el mismo archivo, cada proceso que abre este archivo obtiene una entrada de archivo, pero los punteros de nodo V de las dos entradas de archivo apuntan al mismo nodo V. Organice para que cada proceso tenga su propio desplazamiento actual del archivo y admita diferentes modos abiertos (O_RDONLY, O_WRONLY, ORDWR).

Cuando un proceso crea un proceso hijo por el tenedor, cuando el padre, el descriptor de archivo en el proceso comparten el mismo hijo entrada de la tabla de archivos, lo que significa que el mismo descriptor de fichero de padre e hijo apuntando. En general, vamos a cerrar su fd no deseado después de que el tenedor, como los padres y la comunicación del niño, tienden a cerrarse frente a la necesidad de leer (o escribir) por el extremo de la tubería o socketpair. Solo cuando ningún descriptor de archivo se refiere a la entrada de la tabla de archivos actual, la operación de cierre destruye realmente la estructura de datos de la entrada de la tabla de archivos actual, que es algo similar a la idea de conteo de referencias. La diferencia entre la función de cierre y apagado, que es la programación de la red, el primero sólo en el último utiliza el mango del zócalo del proceso de cerrar cuando realmente desconectado, mientras que el último es sin hablar directamente a un lado de la conexión. Sin embargo, en un entorno multi-hilo, debido a que el padre-hijo hilos de espacio de direcciones de acción, entonces el descriptor de fichero propiedad conjunta, sólo uno, por lo que no puede cerrarse a fd no deseada en el hilo, de lo contrario, dará lugar a otras necesidades de la fd Los hilos también se ven afectados. Debido a que en el padre y el hijo comparten el mismo descriptor de fichero abierto una entrada de archivo, por lo que en algún sistema de programación de servidor, si preforking modelo (pre-servidor genera múltiples procesos hijo, monitorear listenfd para aceptar conexiones por niño) que dará lugar a un fenómeno grupo de choque, servidor derivada múltiples subprocesos cada llamada, aceptar y por lo tanto se ponen a dormir, cuando llega la primera conexión del cliente, a pesar de que sólo un proceso de conectarse, pero todos los procesos son despertados, esto ha llevado a El rendimiento está deteriorado. Ver UNP P657.

Al mismo tiempo, si se llama a exec después de la bifurcación, todos los descriptores de archivo permanecerán abiertos. Esto se puede usar para pasar ciertos descriptores de archivos a programas después de Exec.

También puede copiar explícitamente un descriptor de archivo a través de dup o fcntl, que apunta a la misma entrada de archivo. Copie el descriptor de archivo al valor especificado mediante dup2.

Cada proceso tiene una tabla de descriptores de archivo, un descriptor de fichero de un proceso independiente hay una relación directa entre los dos procesos, el descriptor de archivo en proceso se puede transmitir de forma directa, pero si entre procesos La transferencia pierde su significado, y Unix puede pasar un descriptor de archivo especial a través de sendmsg /recvmsg (consulte la sección 15.7 de UNP). Los primeros tres descriptores de archivo de cada proceso corresponden a la entrada estándar, la salida estándar y el error estándar. Sin embargo, el número de descriptores de archivos que un proceso puede abrir es limitado. Si hay demasiados descriptores de archivos abiertos, habrá un problema con "Demasiados archivos abiertos". En el servidor de red, cuando listenfd llamando aceptación de llamada, encarna error EMFILE productos, principalmente porque el descriptor de archivo es un importante recursos del sistema, se agotan los recursos del sistema, el límite del sistema descriptor de archivo por defecto en un solo proceso en general Es 1024 y se puede ver con el comando ulimit -n. Por supuesto, el proceso puede aumentar el número de descriptores de archivos, pero esto no es el método de solución temporal, porque cuando se trata de servicios simultáneos altos, los recursos limitados del servidor, el agotamiento de recursos es inevitable.

Cuando se combina el modo de disparo epoll nivel de conexión para escuchar lisenfd, un gran número de conexiones de socket próximos si no se manejan cola de conexiones TCP se llenará, listenfd siempre producirá evento de lectura en el servidor en una espera ocupado, en C ++ de código abierto biblioteca de red muduo de la práctica Chen Shuo es preparar de antemano un descriptor de archivo libre cuando se genera un error EMFILE para apagar este archivo libre, un descriptor de archivo llegar a diferentes lugares, y luego aceptar una conexión de socket para obtener la descripción del archivo Luego, cierre de inmediato, desconecte tan elegantemente del cliente y finalmente vuelva a abrir el archivo gratuito, rellene el "Pit", en caso de que vuelva a ocurrir esta situación.

 //al principio del programa antes y " ocupación y " int un descriptor de fichero abierto idlefd = (" /dev /null ", O_RDONLY 
						
Copyright © Conocimiento de Windows All Rights Reserved