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

26
Linux Booteo – Threads y Pipes

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

Page 1: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

Linux

Booteo – Threads y Pipes

Page 2: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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.

Page 3: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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

Page 4: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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

Page 5: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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

Page 6: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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.

Page 7: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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

Page 8: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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.

Page 9: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

Estructura de Pipes

Page 10: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

Pipes #include <unistd.h> int dup2(int fd1, int fd2);

Page 11: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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):

}}

Page 12: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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); }

Page 13: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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)

Page 14: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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

Page 15: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

Proceso vs Thread

Page 16: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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

Page 17: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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

Page 18: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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); }

Page 19: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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); }

Page 20: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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; ... }

Page 21: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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]); ... }

Page 22: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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);

Page 23: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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);

Page 24: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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);}

Page 25: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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);

}

Page 26: Linux Booteo – Threads y Pipes. Booting the kernel 1. Un loader encuentra la imagen de kernel en el disco, lo carga en memoria y comienza a ejecutarla.

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);

}