Identificación de procesos: todos los procesos tienen un número identificativo único (PID = Process Identification).

Además, existe otro tipo de información asociada al proceso:

ps.
Por ejemplo, para ver qué procesos estoy corriendo en estos
momentos, puedo usar:
<T>/usuarios/gyermo$ ps -fu gyermo
UID PID PPID C STIME TTY TIME COMMAND
gyermo 7998 7984 7 12:19:33 pts/td 0:00 ps -fu gyermo
gyermo 7984 7983 1 12:19:25 pts/td 0:00 -ksh
El identificador de proceso aparece en la columna PID. Este número
caracteriza al proceso de forma unívoca. Podemos ver que estoy
ejecutando dos procesos, el correspondiente al propio
ps y el asociado a la shell (el programa que
admite órdenes del teclado y las ejecuta).
kill n, donde n es el PID del proceso que
queréis
matar. Si el proceso no se muere así, podéis intentar
matarlo
con kill -9 n, pero sólo después de
haberlo intentado de la forma anterior.
Creación de procesos en UNIX: los procesos nuevos se crean por "clonación" de los procesos antiguos:

Aunque son dos procesos iguales, cada uno continúa su ejecución de modo independiente. Esto es debido a que la función fork() devuelve un valor distinto a cada proceso:

fork()
devuelve:
printfes para que cada proceso imprima
su identificador de usuario. Por ejemplo:
713: soy el padre. 1022: soy el hijo.Añadid, al final, del programa la orden
sleep(60);,
incluyendo el fichero de cabecera que sea necesario. Ejecutad
el programa en segundo plano para que podáis seguir
tecleando aunque el programa se ejecute y dad la orden
ps apropiada para ver en ejecución tanto al
padre como al hijo.
&. Esto hace que
retoméis
el control inmediatamente y no tengáis que esperar a que
el programa arrancado acabe. Probad la diferencia entre:
sleep 20y
sleep 20 &
Un proceso puede cambiar el programa que está ejecutando mediante la llamada al sistema
execve():#include <unistd.h>
int execve (const char *nomfich, const char *argv[],
const char *envp[]);
El procedimiento habitual para crear un nuevo proceso es llamar primero a
fork y, el nuevo hijo, que llame a execve. No sólo disponéis deexecve para que un proceso
deje definitivamente lo que está haciendo y pase a ejecutar
otro programa. También existen otras funciones de la misma
familia que permiten especificar los parámetros que se le
pasan al nuevo programa de diferentes maneras o que realizan
una búsqueda del programa por el PATH del usuario. Estas funciones
las podéis encontrar en el
resumen.
exec,
haced un programa que ejecute un ls -l mediante
una llamada al sistema de esa familia.
main y devolver
valores
al Sistema Operativo mediante el valor devuelto por
main.
exec, los
argumentos que recibirá la función main del
nuevo
programa son los especificados en los parámetros de la llamada
exec.
fork, el valor que devuelve la función
main ya no es devuelto al Sistema Operativo, sino
que es devuelto a su proceso padre. Para que el proceso padre
pueda recibir ese código de retorno del hijo, ha de efectuar
una llamada al sistema wait, cuyo prototipo es:
pid_t wait(int *stat_loc);Esta llamada al sistema nos devuelve un tipo de datos específico, que será un entero, donde se especificará el error, si se produce, o el PID del proceso hijo a que corresponde la información suministrada por la llamada.
<sys/types.h>. Por ejemplo, para saber el
código de retorno de un hijo, podríamos hacer:
#include <sys/types.h>
[...]
int valor_devuelto;
pid_t pid;
[...]
pid=wait(&valor_devuelto);
[... comprobación de errores estándar ...]
if (WIFEXITED(valor_devuelto))
printf("El valor devuelto por el proceso de PID %d es %d.\n",pid,WEXITSTATUS(valor_devuelto));
wait tiene una llamada prima hermana denominada
waitpid. Su prototipo es:
pid_t waitpid(pid_t pid, int *stat_loc, int options);Como podéis ver en el resumen, los dos parámetros que se añaden a la función son el primero, que permite especificar el PID en concreto sobre el que deseamos conocer su información, y el último, que es un campo de bits que permite especificar opciones. De todas las opciones, sólo nos interesará
WNOHANG.
wait y waitpid,
son el primer ejemplo de llamadas al sistema que disponen de una
versión bloqueante y no bloqueante. Recordemos el diagrama de
estados de UNIX:Diagrama de estados en UNIX:

wait
y esta información no está disponible, el proceso
abandona el
estado de listo y pasa al estado de dormido (bloqueado). Este
estado se caracteriza porque el proceso no consume CPU, es
decir, no sustrae tiempo de cálculo a otros procesos. Cuando
la información está disponible, el proceso se desbloquea y
continúa su ejecución. A efectos del programador,
el programa
se para en la llamada al sistema hasta que la información
esté disponible.
waitpid tiene una
versión no bloqueante y otra, bloqueante. Todo depende de
si especificamos WNOHANG (no bloqueante) o no
lo especificamos (bloqueante) en su tercer parámetro.
waitpid(-1,&valor_devuelto,0);
while (waitpid(-1,&valor_devuelto,WNOHANG)==0)
/* espera ocupada */;
sleep. El proceso padre esperará a que el hijo
concluya mediante waitpid. Haced una versión
bloqueante y otra no bloqueante y ved la diferencia ejecutando
el programa en segundo plano y monitorizando su comportamiento
mediante la orden ps.
wait(&a) es equivalente a
waitpid(-1,&a,0). waitpid es
una llamada que incluye, como caso particular, a
wait.
wait para recoger su
código de retorno (valor devuelto al Sistema Operativo).
ps.
init, que se encarga de
exorcizarlo.

Soy un proceso nieto1 (PID=23840). Mi suma es 0. Soy el proceso padre (PID=23803). Mi suma es 21.Al acabar, el proceso devuelve un código de retorno igual a la suma previamente calculada. De este modo, el padre de todos los procesos conocerá la suma de las últimas cifras del PID de todos sus descendientes, incluído él mismo.
ps
&
ksh
jobs
exec
system
sleep
exec?execl
hay que ponerle NULL como último
parámetro? Me parece una bobería.
[...]
int resultado;
pid_t pid;
[...]
sleep(5);
pid=getpid();
if((waitpid(pid, &resultado, WNOHANG)) == -1){
perror("wait");
return 1;
}
me da el siguiente error:
wait:no child proccessNo lo entiendo porque he hecho un
fork()
antes y ya he tomado la precaución de esperar cinco
segundos para que al hijo le dé tiempo a nacer.