Recursos y límites

Los programas que se ejecutan  en un sistema Linux están sujetas a limitaciones de recursos. Pueden ser límites físicos im,puestos por el hardware (como la memoria), límites impuestos por la política de sistemas (por ejemplo, tiempo de CPU permitido) o límites de ejecución (como el tamaño de un entero o el número máximo de caracteres permitido en un nombre de archivo). La especificación UNIX define algunos de estos límites, que pueden ser determinados por una aplicación. En los próximos capítulos veremos los límites y las consecuencias de romperlos.

El archivo limits.h define varias constantes manifiestas que representan las restricciones impuestas por el sistema operativo. Se incluyen las restricciones que aparecen en la siguiente tabla: recursos_tablaExisten muchos más límites que podemos usar con las aplicaciones creadas, por eso debería acudir a los archivos de cabecera de su instalación.

recursos_nota1El archivo de cabecera sys/resource.h proporciona definiciones para las operaciones de recursos. Incluye las funciones que determinan y configuran los límites en el tamaño permitido de un programa, en la prioridad de ejecución, y en los recursos de archivos:

registro_listado1

id_t es un tipo entero usado para los identificadores de usuario y de grupo.

id_t La estructura rusage, definida en sys/resource.h, se usa para determinar cuánto tiempo de CPU ha usado el programa actual.

rusageDebe contener como mínimo los siguientes miembros:

rusage_2La estructura timeval está definida en sys/time.h y contiene los campos tv_sec y tv_usec, que representan los segundos y los micro segundos respectivamente.

El tiempo de CPU consumido consumido por un programa se divide en tiempo de uso (el tiempo que el propio programa ha consumido ejecutando sus propias instrucciones) y el tiempo de sistema (el tiempo de CPU consumido por el sistema operativo en nombre del programa, es decir, el tiempo consumido en las llamadas al sistema ejecutando entradas y salidas y otras funciones del sistema).

La función getrusage escribe información  sobre el tiempo de CPU en la estructura rusage que indica el parámetro r_usage.

getrusage_2

El parámetro who puede ser una de las siguientes constantes:

whoMás adelante estudiaremos los procesos hijo y las tareas prioritarias, pero por una cuestión de coherencia, vamos a estudiar su implicación en los recursos del sistema aquí. Por ahora es suficiente con decir que cada programa en ejecución tiene una prioridad asociada, y que a los programas con una mayor prioridad se les asigna más tiempo de CPU disponible.

rusage_notaLas aplicaciones pueden determinar y alternar sus prioridades (y las de otros) con las funciones getpriority y setptiority.

getpriority_setpriorityEl proceso que han de examinar o modificar las funciones prioritarias puede ser definido por los identificadores de proceso, por el identificador de grupo o de usuario.

which

El parámetro which específica cómo se ha de tratar al parámetro who. which_whoDe manera que, para determinar la prioridad del proceso actual, debería llamar a

priorityPor defecto, la prioridad es 0. Las prioridades positivas se usan para las tareas secundarias que se ejecutan cuando no hay ninguna otra tarea prioritaria lista para la ejecución. Las prioridades negativas hacen que el programa se ejecute con más frecuencia consumiendo una mayor porción del tiempo CPU disponible. El rango de prioridades va de -20 a +20. Puede resultar confuso porque cuanto más alto es el valor numérico, menor es el nivel de preferencia de ejecución.

getpriority envía una prioridad válida si tiene éxito o -1 con errno si se produce un error. Como -1 es un valor válido, errno debería ser cero antes de llamar a getpriority y a la vuelta debería seguir siendo cero. setpriority envía 0 si tiene éxito, o -1 en caso contrario.

getrlimit y setrlimit pueden leer y establecer los límites de recursos del sistema. Ambas funciones usan una estructura general, rlimit, para describir los límites de los recursos. Se define en sys/resource.h y tiene los siguientes miembros:

rlimitEl tipo definido rlim_t es un tipo entero usado para describir niveles de recursos. Normalmente, el límite menor es un límite recomendado que no se debería superar, porque si se hacen puede provocar que las funciones de biblioteca envíen errores.  Si se supera el límite más duro podría intentar que el sistema intentase finalizar el programa enviándole una señal. Por ejemplo, la señal SIGXCPU excediendo el tiempo límite de la CPU y la señal SIGSEGV excediendo el tamaño límite de los datos. Un programa puede establecer sus propios límites, siempre por debajo del límite superior. También puede reducir dicho límite. Sólo un programa que se ejecute con privilegios de superusuario puede aumentar el límite superior.

Se pueden limitar varios recursos de sistemas. Son especificados por el parámetro resource de las funciones rlimit y se definen en sys/resources tal como indica la tabla de abajo: resourceLa siguiente sección nos mostrará un programa de ejemplo que llamaremos limits.c, y simula una aplicación típica. También configura y rompe el límite de un recurso.

    1. Incluya los archivos de cabecera de todas laas funciones que vamos a usar en este programa:limits_1
    2. La función void escribe una cadena en un archivo temporal 10000 veces y después realiza una operación aritmética para provocar la carga en la CPU:limits_2
    3. La función main llama a work y después usa la función getrusage para descubrir cuánto tiempo de CPU ha usado. Muestra la información en pantalla:limits_3
    4. A continuación, llama a getpriority y a getrlimit para descubrir su prioridad actual y los límites del tamaño del archivo, respectivamente:limits_4
    5. Finalmente, establece un límite en el tamaño del archivo usando setrlimit y llamando de nuevo a work, que falla porque intenta crear un archivo muy largo:limits_5

Cuando ejecute este programa, podrá ver cuántos recursos de la se han consumido y la prioridad de ejecución predeterminada del programa. Una vez que se ha configurado el tamaño límite de un archivo, el programa no puede escribir más de 2048 bytes en un archivo temporal.

limits_salida1Podemos modificar la prioridad del programa iniciándolo con el comando nice. Aquí, puede ver las modificaciones de la prioridad a +10 y, como resultado, el programa tarda un poco más en ejecutarse: limits_salida2

El programa limits llama a la función work para simular las acciones de un programa típico.

como_1Realiza algunos cálculos y produce alguna salida, en este caso, en torno a 150K en un archivo temporal.

como_2Llama a las funciones de recursos para descubrir su prioridad y los límites de tamaño de los archivos.

como_3En este caso, no se han configurado los límites en el tamaño del archivo,  permitiendole crear un archivo tan largo como desee (todo lo que le permita el espacio del disco duro). Después, el programa configura el límite de su tamaño de archivo en 2K e intenta realizar  de nuevo algún trabajo. Esta vez, la función work falla porque no puede crear un archivo temporal tan grande.

como_4 También pueden establecer límites en un programa que se ejecute con una shell en particular con el comando bash ulimit.

En este ejemplo, el mensaje de error «Error de escritura en archivo temporal (Error writing to temporary file)» no aparece tal como esperábamos. Esto se debe a que algunos sistemas (como Linux 2.2 y posteriores) finalizan el programa cuando excede el límite de un recurso. Lo hace enviando una señal, SIGXFSZ. Más adelante veremos más a fondo las señales y su uso.

 atras

Deja un comentario

Este sitio utiliza Akismet para reducir el spam. Conoce cómo se procesan los datos de tus comentarios.