Sistemas operativos modernos

son llamadas al sistema, llamadas a biblioteca u otra cosa. Si un procedimiento puede llevarse a cabo sin invocar una llamada al sistema (es decir, sin saltar al kemel), casi siempre se efectuará en el espacio de usuario por razones de desempeño. No obstante, la mayoría de los procedimien­ tos POSIX sí invoca llamadas al sistema, y, por lo regular, un procedimiento corresponde en for­ ma directa a una llamada al sistema. En unos cuantos casos, sobre todo en los que vanos procedimientos obligatorios no son más que variaciones menores entre ellos, una llamada al sis­ tema se encarga de más de una llamada de biblioteca. 1.6.1 Llamadas al sistema para administración de procesos El primer grupo de llamadas de la figura 1 - 18 se ocupa de la administración de procesos. Fork (bifurcar) es un buen lugar para iniciar la explicación. Fork es la única manera de crear un pro­ ceso nuevo en UNIX. Lo que se crea es un duplicado exacto del proceso original, incluidos to­ dos los descriptores de archivo, registros, etc. Después de fork, el proceso original y la copia (el padre y el hijo) siguen cada cual su camino. Todas las variables tienen valores idénticos en el momento de ejecutar fork, pero, dado que los datos del padre se copian para crear al hijo, los cambios posteriores a uno de ellos no afectan al otro. (El padre y el hijo comparten el tex­ to del programa, que no puede modificarse.) La llamada fork devuelve un valor que es cero en el hijo e igual al identificador del proceso hijo (P ID ) en el padre. Con base en el PID devuel­ to, los dos procesos saben cuál es el padre y cuál el hijo. En general, después de fork, el hijo tendrá que ejecutar código distinto al del padre. Con­ sideremos el caso del shell, que lee un comando de la terminal, produce un proceso hijo, espe­ ra a que el hijo ejecute el comando, y cuando el hijo termina, lee el siguiente comando. Para esperar a que el hijo termine, el padre ejecuta una llamada al sistema waitpid, que simplemen­ te espera hasta que el hijo termina (cualquier hijo, si hay más de uno), waitpid puede esperar a que termine un hijo específico, o a que termine cualquier hijo viejo asignando -1 al primer parámetro. Cuando waitpid termina, la dirección a la que apunta el segundo parámetro, statloc, contendrá la situación de terminación del hijo (normal o anormal, y valor al terminar). Se dis­ pone de varias opciones, que se especifican con el tercer parámetro. Consideremos ahora la manera en que el shell usa fork. Cuando se teclea un comando, el shell produce un proceso nuevo. Este proceso hijo deberá ejecutar el comando del usuario, co­ sa que hace con la llamada al sistema execve, la cual causa que toda su imagen de núcleo sea reemplazada por el archivo que se nombra en su primer parámetro. (En realidad, la llamada al sistema propiamente dicha es exec, pero varios procedimientos de biblioteca distintos la invo­ can con diferentes parámetros y nombres un poco distintos. Aquí trataremos a estos procedi­ mientos como llamadas al sistema.) En la figura 1-19 se muestra un shell muy simplificado que ilustra el uso de fork, waitpid y execve. En el caso más general, execve tiene tres parámetros: el nombre del archivo a ejecutar, un apuntador al arreglo de argumentos y un apuntador al arreglo del entorno. Describiremos estos parámetros en breve. Se proporcionan diversas rutinas de biblioteca, entre ellas execl, execv, execle y execve, para poder omitir parámetros o especificarlos de distintas maneras. En todo es­ te libro usaremos el nombre exec para representar la llamada al sistema que invocan todos estos procedimientos.

RkJQdWJsaXNoZXIy MjI4NDcx