Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en...

Post on 23-Jan-2016

225 views 0 download

Transcript of Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en...

Linux

Booteo – Threads y Pipes

Booting the kernel1. Un loader encuentra la imagen de kernel en el

disco, lo carga en memoria y comienza a ejecutarla

2. El kernel inicializa los dispositivos y sus drivers.3. El kernel monta el filesystem /4. El kernel ejecuta el programa init5. El proceso init ejecuta el resto de los procesos

indicados6. 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.

Estructura de Pipes

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 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) { .... 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

Proceso vs Thread

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_THREADS5

void *ImprimirHola(void *threadid) { int tid; tid = (int)threadid; printf("Hola Mundo! 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);

}