De hecho, hay tres gradaciones en las llamadas al sistema.
- Algunas llamadas al sistema regresan de inmediato. "Inmediatamente" significa que lo único que necesitan es un poco de tiempo de procesador. No hay un límite estricto para cuánto tiempo pueden tomar (excepto en sistemas en tiempo real ), pero estas llamadas regresan tan pronto como se han programado durante el tiempo suficiente.
Estas llamadas generalmente se llaman sin bloqueo . Los ejemplos de las llamadas no bloqueantes son llamadas que simplemente leer un poco de estado del sistema, o hacer un simple cambio en el estado del sistema, tales como getpid
, gettimeofday
, getuid
o setuid
. Algunas llamadas al sistema pueden ser bloqueadas o no bloqueadas dependiendo de las circunstancias; por ejemplo, read
nunca se bloquea si el archivo es una tubería u otro tipo que admite lecturas sin bloqueo y se establece el O_NONBLOCK
indicador .
- Algunas llamadas al sistema pueden tardar un tiempo en completarse, pero no para siempre. Un ejemplo típico es
sleep
.
- Algunas llamadas al sistema no volverán hasta que ocurra algún evento externo. Se dice que estas llamadas están bloqueando . Por ejemplo,
read
invocar un descriptor de archivo de bloqueo es bloqueo, y también lo es wait
.
La distinción entre llamadas de sistema "rápidas" y "lentas" está cerca de no bloquear frente a bloquear, pero esta vez desde el punto de vista del implementador del núcleo. Un syscall rápido es uno que se sabe que puede completarse sin bloquear ni esperar. Cuando el kernel encuentra una syscall rápida, sabe que puede ejecutar la syscall inmediatamente y mantener el mismo proceso programado. (En algunos sistemas operativos con multitarea no preventiva , las llamadas al sistema rápidas pueden no ser preventivas; este no es el caso en los sistemas Unix normales). Por otro lado, una llamada al sistema lenta potencialmente requiere esperar a que se complete otra tarea, por lo que el núcleo debe prepararse para pausar el proceso de llamada y ejecutar otra tarea.
Algunos casos son un poco grises. Por ejemplo, una lectura de disco ( read
de un archivo normal) normalmente se considera sin bloqueo, porque no está esperando otro proceso; solo está esperando el disco, que normalmente toma solo un poco de tiempo para responder, pero no tomará una eternidad (así que ese es el caso 2 anterior). Pero desde la perspectiva del kernel, el proceso tiene que esperar a que se complete el controlador de disco, por lo que definitivamente es una llamada syscall lenta.
Gilles 'SO- deja de ser malvado'
fuente
O_NONBLOCK
bandera. Si se establece el indicador, la llamada al sistema puede completarse sin esperar nada más, por lo que no se bloquea y el núcleo puede tratarla como una llamada al sistema rápida.Una llamada lenta al sistema es algo así como un socket TCP read (): si no tiene O_ASYNC (o lo que sea) configurado, puede esperar para siempre.
Una llamada rápida al sistema es algo así como gettimeofday () o getpid (), los cuales devuelven información al proceso que el núcleo tiene disponible de inmediato.
Las lecturas de disco pertenecen a la categoría de llamadas lentas al sistema. Si un proceso hace una lectura () en un archivo de disco verdadero, un descriptor de archivo, el núcleo puede tener que leer en uno o más bloques de disco para satisfacer la lectura. Dependiendo de la estructura en disco del sistema de archivos subyacente, esto puede significar leer el inodo en disco para obtener el número de bloque de disco de un "bloque indirecto", leer el bloque indirecto para obtener el bloque de datos y luego leer el bloque de datos en sí . Bastante lento, al menos en términos de ciclos de CPU por acceso al disco, probablemente peor hoy que en los viejos tiempos.
No he visto esto en años, pero la "mitad inferior" del antiguo código de controlador de dispositivo de la unidad de disco Unix bloquearía las señales / interrupciones para que fuera más fácil mantener la integridad del sistema de archivos en el disco. Ocasionalmente, un controlador defectuoso o un disco defectuoso nunca entregarían el bloque de disco que un proceso había solicitado, y el proceso durmió para siempre. Incluso un kill -9 no le hizo nada.
fuente