ps lf
de linux para ver el árbol de procesos padre e hijo.ps lp <pid>
para averguar que proceso se corresponde con un pid
kill -9 <pid>
para «matar» un proceso con un determinado pid
En C la instrucción para crear procesos es fork(). Las funciones system() y exec*() lo que hacen es llamar a programas ya existenetes para crear un proceso, en cambio fork no llama a ningún otro programa existente sino que se replica el proceso donde ese ejecuta dicha instrucción.
#include <unistd.h>
#include <stdio.h>
void main(void) {
pid_t id_actual, id_padre;
id_actual = getpid();
id_padre = getppid();
printf("Mi PID es: %d\n", id_actual);
printf("El PID de mi papa es: %d\n", id_padre);
}
juanjo@debian:~/fork$ gcc forkp1.c -o forkp1
juanjo@debian:~/fork$ ./forkp1
Mi PID es: 700
El PID de mi papa es: 678
juanjo@debian:~/fork$ ps
PID TTY TIME CMD
678 pts/0 00:00:00 bash
701 pts/0 00:00:00 ps
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
void main(void) {
pid_t id_actual, id_padre, pid;
pid = fork();
if (pid == -1) { // Hubo error
printf("Hubo un problema de impotencia al crear el hijo");
exit(-1); }
// Si todo va bien y se crea el hijo tenemos que hacer
// que el programa ejecute un código con distinto para cada
// proceso
if (pid == 0) { // Nos encontramos en el hijo
printf ("Soy el proceso hijo\n\t");
printf(" Mi PID es %d, y el mi papa %d\n",getpid(),getppid());
} else { // Nos encontramos en el padre
printf("Yo soy el padre de la criatura:\n\t");
printf("Mi PID es %d, el de mi padre (abuelo de la criatura) es %d.\n\t",
getpid(),getppid());
printf("Mi hijo si es de verdad hijo mio deberia tener el PID %d.\n",pid);
}
exit(0);
}
Si ejecutamos obtenemos este resultado:
juanjo@debian:~/fork$ ./forkp2
Yo soy el padre de la criatura:
Mi PID es 1018, el de mi padre (abuelo de la criatura) es 678.
Mi hijo si es de verdad hijo mio deberia tener el PID 1019.
juanjo@debian:~/fork$ Soy el proceso hijo
Mi PID es 1019, y el mi papa 1
El proceso hijo dice que su padre es PID=1
. Esto ocurre porque cuando el hijo ejecuta la instrucción el proceso padre ya ha terminado su ejecución de manera que el proceso del S.O. adopta todos los procesos hijos del padre que acaba de terminar dejando procesos huérfanos. Para evitar crear procesos huérfanos tenemos la función wait()
que nos permite parar un proceso hasta que un proceso hijo no termine.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
void main(void) {
pid_t id_actual, id_padre, pid;
pid = fork();
if (pid == -1) { // Hubo error
printf("Hubo un problema de impotencia al crear el hijo");
exit(-1); }
// Si todo va bien y se crea el hijo tenemos que hacer
// que el programa ejecute un código con distinto para cada
// proceso
if (pid == 0) { // Nos encontramos en el hijo
printf ("Soy el proceso hijo\n\t");
printf(" Mi PID es %d, y el mi papa %d\n",getpid(),getppid());
} else { // Nos encontramos en el padre
id_actual = wait(NULL);
printf("Yo soy el padre de la criatura:\n\t");
printf("Mi PID es %d, el de mi padre (abuelo de la criatura) es %d.\n\t",
getpid(),getppid());
printf("Mi hijo si es de verdad hijo mio deberia tener el PID %d.\n",pid);
}
exit(0);
}
Ahora si ejecutamos el nuevo código:
juanjo@debian:~/fork$ ./forkp3
Soy el proceso hijo
Mi PID es 1072, y el mi papa 1071
Yo soy el padre de la criatura:
Mi PID es 1071, el de mi padre (abuelo de la criatura) es 678.
Mi hijo si es de verdad hijo mio deberia tener el PID 1072.
El abuelo será el interprete de comando del sistema:
juanjo@debian:~/fork$ ps
PID TTY TIME CMD
678 pts/0 00:00:00 bash
1100 pts/0 00:00:00 ps
juanjo@debian:~/fork$
Creación de un proceso que cree un hijo y éste a su vez cree otro proceso:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
void main(void) {
pid_t pid, Hijo_pid, pid2, Hijo2_pid;
pid = fork(); // Soy el abuelo e intento crear a mi hijo
if (pid == -1) { // Hubo error
printf("Hubo un problema de impotencia al crear el hijo");
exit(-1);
}
// Si todo va bien y se crea el hijo tenemos que hacer
// que el programa ejecute un código con distinto para cada
// proceso if (pid == 0) {
// Nos encontramos en el hijo
pid2 = fork(); //soy el hijo y creo al nieto
switch(pid2) {
case -1: //error
printf("No se ha podido crear el proceso nieto en el hijo");
exit(-1);
break;
case 0: // Estoy en el nieto
printf("\t\tSoy el proceso NIETO %d, Mi padre es = %d \n",
getpid(),getppid());
break;
default: //proceso padre
Hijo2_pid=wait(NULL); //espero a que termine nieto, que es mi hijo.
printf("\t\tSoy el proceso HIJO %d, Mi padre es = %d \n",
getpid(),getppid());
printf("\tMi hijo: %d terminó.\n", Hijo2_pid);
}
} else {
// Nos encontramos en el abuelo
id_actual = wait(NULL); // Espero a que termine mi hijo, que a su vez espera que termine el nieto
printf("Yo soy el abuelo de las dos criaturas anteriores:\n\t");
printf("Mi PID es %d, el de mi padre (Sistema Operativo) es %d.\n\t", getpid(),getppid());
printf("Mi hijo si es de verdad hijo mio deberia tener el PID %d.\n",pid);
printf("A mi nieto no lo puedo conocer, solo reconozco a mi generación inmediata\n");
printf("Para conocer a mi NIETO debería implementar algún sitema de comunicación entre procesos.\");
}
exit(0);
}
Realiza un programa en C que cree un proceso (tendremos 2 procesos el padre y el hijo)
int a;
a=6;
Valor inicial de la variable = 6
Variable proceso hijo = ?
Variable proceso padre = ?
Realiza un programa en C que cree un proceso y luego fuerza para que se muestre dicho proceso como un proceso zombie
aaaa