1 Booteo – Threads y PipesLinux Booteo – Threads y Pipes
2 Booting the kernel Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla El kernel inicializa los dispositivos y sus drivers. El kernel monta el filesystem / El kernel ejecuta el programa init El proceso init ejecuta el resto de los procesos indicados El ultimo proceso que el init ejecuta como parte de la secuencia de booteo es el proceso de login.
3 GRUB Grand Unified BootloaderPermite navegar por los filesystems sin cargar el kernel Tiene un minishell que permite hacer multiples booteos con parámetros distintos. Ejemplo: root (hd0,2) kernel /boot/vmlinuz root=/dev/hda3 -s noacpi initrd /boot/initrd boot
4 El proceso Init Este programa se encuentra en /sbinEjecuta programas en un orden específico La mayoría de los linux usan el estilo System V, algunos otros usan el de BSD. Existen runlevels (0 a 6), que indican cuales son los procesos que deberían estar en ejecución. (el kernel ejecuta o termina servicios según el runlevel indicado) /etc/inittab /etc/rc*.d: Snntexto y Knntexto
5 /etc/inittab Contiene lineas del estilo: Id: 5:initdefault:Esta linea indica que el runlevel por default es el 5 l5:5:wait:/etc/rc.d/rc 5 Esta linea dispara la mayoría de las configuraciones y servicios de los directorios /etc/rc*.d y /etc/init.d Wait : Indica que ejecuta todos los comandos y quede a la espera de su finalización. Respawn: Siempre existe una copia del programa ejecutando 1:2345:respawn:/sbin/mingetty tty1 El programa getty provee el prompt de login. Sysinit : Todo aquello que se debe ejecutar antes de entrar en los runlevels.
6 Shutting Down Shutdown –r +10Pasado el tiempo de gracia, el programa shutdown le indica a init que cambie a runlevel 0 para halt o a runlevel 6 para reboot. Entrando en runlevel 0 o 6, el init mata todo proceso que puede. Los primeros comandos del rc0 o rc6, bloquean archivos de sistema, luego desmontan los filesystems distintos a root, remonta el root como solo lectura, graba los buffers con el programa sync y por ultimo ejecuta halt, reboot o poweroff.
7 Algunos archivos especiales/bin/sh, /etc/bashrc, /etc/profile, /etc/profile.d /etc/resolv.conf, /etc/nsswitch, /etc/hosts, /etc/hosts.allow, /etc/hosts.deny /etc/passwd, /etc/shadow /etc/fstab /etc/mtab /etc/inittab, /etc/rc*.d, /etc/init.d /etc/ld.so.conf
8 Pipes Los pipes, son archivos especiales que se crean para intercambiar información entre procesos. Normalmente se los puede usar desde la linea de comandos (con el símbolo “|” ): who | more Esto le indica al interprete de comandos que ejecute dos procesos “who y more” y una la salida del comando who a la entrada del comando more.
9 Estructura de Pipes
10 Pipes #include
11 Pipes (who | more) /* Archivo del programa whomore.c */ main() {int fds[2] pipe(fds); /* Hijo1 reconecta stdin a parte baja del pipe y cierra alta */ if (fork() == 0) { dup2(fds[0], 0); close(fds[1]); execlp(“more”,”more”,0); } else { /* Hijo2 reconecta stdout a parte alta del pipe y cierra baja */ if ( fork() == 0 ) { dup2(fds[1], 1); close(fds[0]); execlp(“who”, “who”, 0); else { /* padre cierra ambas partes y espera a los hijos */ wait(0); wait(0):
12 Otro Ejemplo con pipes int main(int argc, char *argv[]) { int pfd[2];pid_t cpid; char buf[80]; if (pipe(pfd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } write(pfd[1], argv[0], strlen(argv[0])); cpid = fork(); if (cpid == -1) { perror("fork"); exit(EXIT_FAILURE); } if (cpid == 0) { while (read(pfd[0], &buf, 1) > 0) { .... } close(pfd[0]); _exit(EXIT_SUCCESS);
13 Posix Threads Un thread es una lista de instrucciones que puede ser planificado para ejecutar por el sistema operativo Normalmente se trata de un procedimiento dentro de un programa que puede ejecutarse independientemente del programa. Como se implementa en UNIX. IEEE POSIX c standard (1995)
14 Proceso vs Thread Un proceso en LINUX tiene asociado:Id de proceso, id de grupo de proceso, id de grupo, id de usuario Mapa de Memoria Ambiente Directorio de ejecución Instrucciones de programa Registros Stack Heap Descriptores de Archivos Atenciones a señales Librerías compartidas Herramientas de comunicación cola de mensajes, pipes, semáforos o memoria compartida
15 Proceso vs Thread
16 Pthreads El Api de Pthreads esta dividido en: Convensiones:Manejo de Threads Mutex Variables de Condición Convensiones: pthread_ (rutinas) // pthread_attr_ (atributos) pthread_mutex_ (mutex) // pthread_mutexattr_ pthread_cond_ (cond. Var) // pthread_condattr_ pthread_key_ (data keys) Compilacion con pthreads gcc -pthread
17 Rutinas de Pthreads Rutinas:pthread_create (thread,attr,start_routine,arg) pthread_exit (status) pthread_attr_init (attr) pthread_attr_destroy (attr) Atributos: pthread_attr_init pthread_attr_destroy
18 Pthread Ejemplo #include
19 Pthread Ejemplo int main(int argc, char *argv[]) {pthread_t threads[NUM_THREADS]; int rc, t; for(t=0;t
20 Pthreads: Pasaje de argumentosstruct thread_data{ int thread_id; int sum; char *message; }; struct thread_data thrd_data_A[NUM_THREADS]; void *ImprimirHola(void *threadarg) { struct thread_data *my_data; ... my_data = (struct thread_data *) threadarg; taskid = my_data->thread_id; sum = my_data->sum; hello_msg = my_data->message; }
21 Pthreads: Pasaje de argumentosint main (int argc, char *argv[]) { ... thrd_data_A[t].thread_id = t; thrd_data_A[t].sum = sum; thrd_data_A[t].message = messages[t]; rc = pthread_create(&threads[t], NULL, ImprimirHola, (void *) &thrd_data_A[t]); }
22 Otro Ejemplo de PthreadsEstructura de datos para prod/cons typedef struct { char buf[BSIZE]; pthread_mutex_t lock; pthread_cond_t less; pthread_cond_t more; int nextin; int nextout; int occupied; } buffer_t; Funciones: void consumer(buffer_t * b); void producer(buffer_t * b); char consume(buffer_t * b); void produce(buffer_t * b, char item);
23 Otro Ejemplo de PthreadsVariables: buffer_t *buffer; pthread_mutexattr_t mutex_attr; pthread_condattr_t cond_attr; buffer->occupied = buffer->nextin = buffer->nextout = 0; Creación de vars de condición y mutex correspondientes: pthread_mutexattr_init(&mutex_attr); pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED); pthread_mutex_init(&buffer->lock, &mutex_attr); pthread_condattr_init(&cond_attr); pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED); pthread_cond_init(&buffer->less, &cond_attr); pthread_cond_init(&buffer->more, &cond_attr);
24 Otro Ejemplo de Pthreadsvoid consumer(buffer_t * b){ char item; printf("Consumidor - %d\n", getpid()); while (1) { item = consume(b); if (item == '\0') break; putchar(item); } } void producer(buffer_t * b) { int item; printf(“ Productor - %d\n", getpid()); while (1) { item = getchar(); if (item == EOF) { produce(b, '\0'); break; } else produce(b, (char) item); } } Prg Principal if (fork() == 0) { consumer(buffer); exit(0);} else { producer(buffer); exit(0);}
25 Otro Ejemplo de Pthreadschar consume(buffer_t * b){ char item; pthread_mutex_lock(&b->lock); printf("Consume\n"); while (b->occupied == 0) pthread_cond_wait(&b->more, &b->lock); item = b->buf[b->nextout++]; b->nextout %= BSIZE; b->occupied--; pthread_cond_signal(&b->less); pthread_mutex_unlock(&b->lock); return (item); }
26 Otro Ejemplo de Pthreadsvoid produce(buffer_t * b, char item) { pthread_mutex_lock(&b->lock); printf("Produce\n"); while (b->occupied == BSIZE) pthread_cond_wait(&b->less, &b->lock); b->buf[b->nextin++] = item; b->nextin %= BSIZE; b->occupied++; pthread_cond_signal(&b->more); pthread_mutex_unlock(&b->lock); }