290 likes | 623 Views
Linux. Booteo – Threads y Pipes. 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
E N D
Linux Booteo – Threads y Pipes
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.
GRUB Grand Unified Bootloader • Permite 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
El proceso Init • Este programa se encuentra en /sbin • Ejecuta 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
/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.
Shutting Down • Shutdown –r +10 • Pasado 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.
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
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.
Pipes • #include <unistd.h> • int dup2(int fd1, int fd2);
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 */ close(fds[0]); close(fds[1]); wait(0); wait(0): } }
Otro Ejemplo con pipes • intmain(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) { • .... • write(pfd[1], argv[0], strlen(argv[0])); • } • close(pfd[0]); • _exit(EXIT_SUCCESS); • }
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 1003.1c standard (1995)
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
Pthreads • El Api de Pthreads esta dividido en: • 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
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
Pthread Ejemplo • #include <pthread.h> • #include <stdio.h> • #include <stdlib.h> • #define NUM_THREADS 5 • void *ImprimirHola(void *threadid) • { • int tid; • tid = (int)threadid; • printf("HolaMundo!Soy el thread #%d!\n", tid); • pthread_exit(NULL); • }
Pthread Ejemplo • int main(int argc, char *argv[]) • { • pthread_t threads[NUM_THREADS]; • int rc, t; • for(t=0;t<NUM_THREADS;t++){ • printf("In main: creating thread %d\n", t); • rc = pthread_create(&threads[t], NULL, ImprimirHola, (void *)t); • if (rc){ • printf("ERROR; No se pudo crear thread nro %d\n", rc); • exit(-1); • } • } • pthread_exit(NULL); • }
Pthreads: Pasaje de argumentos • struct 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; • ... • }
Pthreads: Pasaje de argumentos • int 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]); • ... • }
Otro Ejemplo de Pthreads • Estructura 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);
Otro Ejemplo de Pthreads • Variables: • 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);
Otro Ejemplo de Pthreads • void 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);}
Otro Ejemplo de Pthreads • char 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); • }
Otro Ejemplo de Pthreads • void 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); • }