Procesos
En Linux los procesos se identifican con un numero entero denominado ID de proceso o PID. Al proceso que ejecuta la solicitud para la creación de un proceso se le suele llamar proceso padre, y al proceso creado se le suele llamar proceso hijo. El comando ps El comando ps sirve para mostrar información sobre procesos, su sintaxis (POSIX) es la siguiente: ps [-aA] [-G grouplist] [-o format] ... [-p proclist] [-t termlist] [-U userlist] Ver: man ps
Librerías • stdio.h (cd /usr/include) • unistd.h (cd /usr/include) • sys/types.h (cd /usr/include/sys) • En general, son típicas librerías en la codificación en C ya que contiene una serie de funciones comúnmente utilizados.
Librerías <stdio.h>: Librería que contiene funciones de cabeceras de entrada/salida. : Librería que contiene funciones para el manejo de directorios y archivos. <sys/types.h>: Librería que contiene funciones de búsqueda y ordenamiento de directorios y manipulación de archivos
Identificadores de Usuarios y Procesos • Las funciones C que se utilizan para obtener el identificador del proceso (PID) o el identificador de usuario (UID) son: – getpid – getppid – getuid
getpid y getppid • NOMBRE getpid, getppid: obtiene el identificador de proceso.
• SINTAXIS #include (define a getpid y getppid) pid_t getpid(void); pid_t getppid(void); • (pid_t es un entero largo con el ID del proceso)
• DESCRIPCIÓN – getpid devuelve el identificador de proceso del proceso actual. Esto es usado normalmente por rutinas que generan nombres únicos de ficheros temporales. – getppid devuelve el identificador de proceso del padre del proceso actual.
getuid • NOMBRE getuid, geteuid: devuelve la identidad del usuario.
• SINOPSIS #include #include <sys/types.h> uid_t getuid(void); uid_t geteuid(void);
• DESCRIPCIÓN getuid devuelve el identificador de usuario real del proceso actual. El identificador real corresponde con el del proceso invocador.
• ERRORES Estas funciones siempre funcionan.
fork •
NOMBRE Fork: crean un proceso hijo.
•
SINOPSIS #include pid_t fork(void);
•
DESCRIPCIÓN fork crea un proceso hijo que difiere de su proceso padre sólo en su PID y PPID, y en el hecho de que el uso de recursos esté asignado a 0. Los candados de fichero (file locks) y las señales pendientes no se heredan. En linux, fork está implementado usando páginas de copia-en-escritura (copy-on-write), así que la única penalización en que incurre fork es en el tiempo y memoria requeridos para duplicar las tablas de páginas del padre, y para crear una única estructura de tarea (task structure) para el hijo.
•
VALOR DEVUELTO En caso de éxito, se devuelve el PID del proceso hijo en el hilo de ejecución de su padre, y se devuelve un 0 en el hilo de ejecución del hijo. En caso de fallo, se devolverá un -1 en el contexto del padre, no se creará ningún proceso hijo, y se pondrá en errno un valor apropiado.
•
ERRORES EAGAIN: fork no puede reservar sufficiente memoria para copiar las tablas de páginas del padre y alojar una estructura de tarea para el hijo. ENOMEM: fork no pudo obtener las necesarias estructuras del núcleo porque la cantidad de memoria era escasa.
Compilación y ejecución de un programa en C • Comando de compilación: gcc -o <nombre archivo que se crea> <nombre archivo fuente con extensión .c> Ejemplo: gcc -o prueba archivo.c
• Comando de ejecución: ./<nombre archivo ejecutable que se creó en gcc> Ejemplo: ./prueba
Ejemplo 1: #include <stdio.h> int main() { int num1,num2,suma; scanf(“Ingrese Primer Número”, num1); scanf(“Ingrese Segundo Número”, num2); int suma=num1+num2; printf(“La suma de %d + %d = %d”; num1,num2,suma); } Grabar el archivo como: numero.c Compilación: gcc -o numero numero.c Ejecución: ./numero
Ejemplo 2: #include <stdio.h> int main() { printf(“Hola a todos!!\n”); exit(0); } Grabar el archivo como: hola.c Compilación: gcc –o hola hola.c Ejecución: ./hola
El siguiente programa imprime el identificador del proceso actual, del proceso padre y del propietario: #include <stdio.h> #include <sys/types.h> #include int main(void) { printf("ID de proceso: %ld\n", (long)getpid()); printf("ID de proceso padre: %ld\n", (long)getppid()); printf("ID de usuario propietario: %ld\n", (long)getuid()); return 0; } NOTA: Al finalizar de codificar, grabarlo con el nombre: proceso.c
#include <stdio.h> #include <sys/types.h> #include int main(void) { int i; int padre; padre=1; for (i=0; i<3; i++) { if (padre==1) { if (fork()== 0) /* Proceso hijo */ { fprintf(stdout, "Este es el proceso hijo con padre %ld\n", (long)getppid()); padre = 0; } else /* Proceso padre */ { fprintf(stdout, "Este es el proceso padre con ID %ld\n", (long)getpid()); padre = 1; } } } sleep(50); return 0; } NOTA: grabrar con el nombre: padrehijo.c
El siguiente código produce un árbol de procesos como el de la figura: