Anuncios
espera, esperapid – espera a que el proceso cambie de estado
#include <sys/types.h> #include <sys/wait.h> |
Todas estas llamadas al sistema se utilizan para esperar cambios de estado en un hijo del proceso de llamada y obtener información sobre el hijo cuyo estado ha cambiado. Se considera que un cambio de estado es: la terminación del niño; el niño fue detenido por una señal; o el niño fue reanudado por una señal. En el caso de un hijo despedido, realizar una espera permite que el sistema libere los recursos asociados con el hijo; si no se realiza una espera y luego se termina, el niño permanece en un estado «zombi» (ver NOTAS a continuación).
Si un niño ya ha cambiado de estado, estas llamadas regresan inmediatamente. De lo contrario, se bloquean hasta que un niño cambia de estado o un manejador de señales interrumpe la llamada (asumiendo que las llamadas al sistema no se reinician automáticamente usando el SA_RESTART Bandera de
sigaction(2)). En el resto de esta página, un niño cuyo estado ha cambiado y que aún no ha sido atendido por una de estas llamadas al sistema se denomina
esperable.
esperar () y esperarpid ()
los Espere() la llamada al sistema suspende la ejecución del proceso actual hasta que uno de sus hijos finaliza. La llamada esperar (y estado) es equivalente a:
los esperar() la llamada al sistema suspende la ejecución del proceso actual hasta que un niño especificado por pid el argumento ha cambiado de estado. Por defecto,
esperar() espera solo a los hijos terminados, pero este comportamiento se puede modificar a través del
opciones argumento, como se describe a continuación.
El valor de pid puede ser:
Etiqueta | Descripción |
---|---|
<-1 | lo que significa esperar cualquier proceso hijo cuyo ID de grupo de proceso sea igual al valor absoluto de pid. |
-1 | es decir, esperar cualquier proceso hijo. |
0 | es decir, esperar cualquier proceso hijo cuyo ID de grupo de procesos sea igual al del proceso de llamada. |
> 0 | lo que significa esperar al niño cuyo ID de proceso es igual al valor de pid. |
El valor de opciones es un OR de cero o más de las siguientes constantes:
Etiqueta | Descripción |
---|---|
WNOHANG | Regrese inmediatamente si ningún niño ha salido. |
WUNTRACED | también regresa si un niño se ha detenido (pero no se ha rastreado a través de trazar(2)). Estado para rastreado Los niños que se han detenido se proporcionan incluso si no se especifica esta opción. |
WC CONTINUADO | (Desde Linux 2.6.10) también se devuelve si un niño detenido se ha reanudado mediante la entrega de SIGCONT. |
(Para opciones exclusivas de Linux, consulte a continuación).
WUNTRACED y WC CONTINUADO opciones solo son efectivas si el
SA_NOCLDSTOP la bandera no se ha establecido para el
SIGCHLD señal (ver sigaction(2)).
Si estado No es nulo, Espere() y esperar() almacenar información de estado en el En t al que apunta. Este número entero se puede inspeccionar con las siguientes macros (que toman el número entero como argumento, no como un puntero, como se hace en Espere() y esperar()!):
Etiqueta | Descripción |
---|---|
WIFEXITED (estado) | devuelve verdadero si el niño terminó normalmente, es decir, llamando Salida(3) o _Salida(2), o volviendo de main (). |
WEXITSTATUS (estado) |
devuelve el estado de salida del niño. Consiste en los 16-8 bits menos significativos del |
WIFSIGNALED (estado) |
devuelve verdadero si el proceso hijo fue terminado por una señal. |
WTERMSIG (estado) |
devuelve el número de la señal que provocó la finalización del proceso hijo. Esta macro solo debe emplearse si |
WCOREDUMP (estado) |
devuelve verdadero si el hijo produjo un volcado de memoria. Esta macro solo debe emplearse si |
WIFSTOPPED (estado) |
devuelve verdadero si el proceso hijo se detuvo mediante la entrega de una señal; esto solo es posible si la llamada se realizó usando |
WSTOPSIG (estado) |
devuelve el número de la señal que hizo que el niño se detuviera. Esta macro solo debe emplearse si |
WIFCONTINUADO (estado) |
(Desde Linux 2.6.10) devuelve verdadero si el proceso hijo se reanudó mediante la entrega de |
waitid ()
los esperar() llamada al sistema (disponible desde Linux 2.6.9) proporciona un control más preciso sobre qué cambios de estado secundario esperar.
los
tipo de identificación y
identificación Los argumentos seleccionan a los niños a esperar, de la siguiente manera:
Etiqueta | Descripción |
---|---|
tipo de identificación == P_PID |
Espere al niño cuyo ID de proceso coincide |
tipo de identificación == P_PGID |
Espere a cualquier niño cuyo ID de grupo de proceso coincida |
tipo de identificación == FÉRETRO |
Espere a cualquier niño; |
Los cambios de estado secundario a los que se debe esperar se especifican haciendo OR en uno o más de los siguientes indicadores en |
|
WEXITED |
Espere a los niños que hayan terminado. |
WSTOPPED |
Espere a los niños que hayan sido detenidos mediante la entrega de una señal. |
WC CONTINUADO |
Espere a los niños (detenidos anteriormente) que hayan sido reanudados con el parto de |
Las siguientes banderas pueden además ser colocadas en OR en |
|
WNOHANG |
Como para |
WNOWAIT |
Deje al niño en un estado de espera; se puede usar una llamada de espera posterior para recuperar nuevamente la información del estado del niño. |
Al regresar exitosamente, |
|
si_pid |
El ID de proceso del niño. |
si_uid |
La identificación de usuario real del niño. (Este campo no se establece en la mayoría de las demás implementaciones). |
si_signo |
Siempre configurado en |
si_status |
O bien el estado de salida del niño, dado a |
si_code |
Establecer en uno de: |
Si WNOHANG fue especificado en
opciones y no había niños en estado de espera, entonces
esperar() devuelve 0 inmediatamente y el estado del
siginfo_t estructura apuntada por
infop no está especificado. Para distinguir este caso de aquél en el que un niño estaba en un estado de espera, ponga a cero el
si_pid antes de la llamada y compruebe si hay un valor distinto de cero en este campo después de que la llamada regrese.
Espere(): en caso de éxito, devuelve el ID de proceso del hijo terminado; en caso de error, se devuelve -1.
esperar(): en caso de éxito, devuelve el ID de proceso del niño cuyo estado ha cambiado; en caso de error, se devuelve -1; si WNOHANG fue especificado y ningún niño (s) especificado por pid aún ha cambiado de estado, luego se devuelve 0.
esperar(): devuelve 0 en caso de éxito o si
WNOHANG fue especificado y ningún niño (s) especificado por
identificación aún ha cambiado de estado; en caso de error, se devuelve -1.
Cada uno de estos conjuntos de llamadas
errno a un valor apropiado en caso de error.
Etiqueta | Descripción |
---|---|
ECHILD |
(por |
ECHILD |
(por |
EINTR |
WNOHANG no se configuró y una señal desbloqueada o un SIGCHLD fue capturado. |
EINVAL |
los |
Un niño que termina, pero no ha sido esperado, se convierte en «zombi». El kernel mantiene un conjunto mínimo de información sobre el proceso zombi (PID, estado de terminación, información sobre el uso de recursos) para permitir que el padre espere más tarde para obtener información sobre el hijo.
Mientras no se elimine un zombi del sistema mediante una espera, consumirá un espacio en la tabla de procesos del kernel y, si esta tabla se llena, no será posible crear más procesos. Si un proceso padre termina, entonces sus hijos «zombies» (si los hay) son adoptados por en eso(8), que automáticamente realiza una espera para eliminar a los zombies.
POSIX.1-2001 especifica que si la disposición de
SIGCHLD se establece en
SIG_IGN o la
SA_NOCLDWAIT la bandera está puesta para
SIGCHLD (ver
sigaction(2)), entonces los niños que terminan no se convierten en zombies y una llamada a
Espere() o
esperar() bloqueará hasta que todos los hijos hayan terminado y luego fallará con
errno ajustado a
ECHILD. (El estándar POSIX original dejó el comportamiento de configuración
SIGCHLD para
SIG_IGN sin especificar.) Linux 2.6 cumple con esta especificación. Sin embargo, Linux 2.4 (y versiones anteriores) no lo hace: si un
Espere() o
esperar() la llamada se realiza mientras
SIGCHLD se ignora, la llamada se comporta como si
SIGCHLD no estaban siendo ignorados, es decir, la llamada se bloquea hasta que el siguiente hijo termina y luego devuelve el ID de proceso y el estado de ese hijo.
En el kernel de Linux, un subproceso programado por el kernel no es una construcción distinta de un proceso. En cambio, un subproceso es simplemente un proceso que se crea utilizando el método exclusivo de Linux.
clon(2) llamada al sistema; otras rutinas como el portátil
pthread_create(3) la llamada se implementa utilizando
clon(2).
Antes de Linux 2.4, un subproceso era solo un caso especial de un proceso y, como consecuencia, un subproceso no podía esperar a los hijos de otro subproceso, incluso cuando este último pertenece al mismo grupo de subprocesos. Sin embargo, POSIX prescribe dicha funcionalidad y, desde Linux 2.4, un subproceso puede, y de forma predeterminada lo hará, esperar a los hijos de otros subprocesos en el mismo grupo de subprocesos.
Los siguientes específicos de Linux
opciones son para usar con niños creados con
clon(2); no se pueden usar con
esperar():
Etiqueta | Descripción |
---|---|
__WCLONE |
Espere sólo a los niños «clonados». Si se omite, espere sólo a los hijos «no clonados». (Un niño «clon» es aquel que no emite ninguna señal, o una señal que no sea |
__PARED |
(Desde Linux 2.4) Espere a todos los niños, independientemente del tipo («clon» o «no clon»). |
__WNOTHREAD |
(Desde Linux 2.4) No espere a los hijos de otros subprocesos en el mismo grupo de subprocesos. Este era el valor predeterminado antes de Linux 2.4. |
El siguiente programa demuestra el uso de tenedor(2) y
esperar(2). El programa crea un proceso hijo. Si no se proporciona ningún argumento de línea de comando al programa, entonces el niño suspende su ejecución usando
pausa(2), para permitir que el usuario envíe señales al niño. De lo contrario, si se proporciona un argumento en la línea de comandos, el hijo sale inmediatamente, utilizando el entero proporcionado en la línea de comandos como estado de salida. El proceso padre ejecuta un ciclo que monitorea al niño usando
esperar(2) y utiliza las macros W * () descritas anteriormente para analizar el valor del estado de espera.
La siguiente sesión de shell demuestra el uso del programa:
|