Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

22
Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads

Transcript of Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Page 1: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

1

Threads

Page 2: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

2

fork ( )

• Produce una copia del proceso que genera la system call. Esta copia es idéntica a la original.

• Cada proceso (la copia y el original) tiene su espacio de memoria, sus propias variables que también son independientes. El proceso hijo puede modificar cualquiera de sus variables sin afectar la copia de éstas que pertenece al padre.

• La independencia entre ambos procesos brinda protección y estabilidad. Sin embargo cuando varios procesos trabajan sobre el mismo problema, se producen inconvenientes.

Page 3: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

3

Threads

• Se los llama Light Weight Processes (LWP) o hilos.

• Cuando un programa crea un thread – No se generan copias de los recursos– Ambos hilos de ejecución comparten el mismo espacio de

memoria, file descriptors y otros recursos de sistema que posea el creador del thread.

• Cada thread tiene un único thread_id, puntero de stack y variables locales.

• Si cualquier thread llama a cualquiera de las funciones del grupo exec todos los demás threads terminan.

• Ver codigo de fork

• Ver codigo de thread.

Page 4: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

4

ConcurrenciaLa definicion exacta de concurrencia introducida por Dijkstra indica que

Sn sentencias son concurrentes cuando dadas "S1 | S2 | S3 | Sn" todas ellas pueden ser ejecutadas al momento de ser llamadas.En nuestro caso N procesos son concurrentes cuando su ejecucion se realiza en forma simultanea. (llamese para tomar un recurso, presentar datos etc)(Estrictamente esto es imposible sobre la arquitectura IA32)

Un programa concurrente es un programa que tiene más de una línea lógica de ejecución. Dicho de otra forma, es un programa que parece que varias partes del mismo se ejecutan simultáneamente -aunque no tenga por que ser así-.

Page 5: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

5

Beneficios de concurrencia

• Bloqueo de IO: Los procesos que utilizan IO tiene 3 opciones de manejarlo:– De forma serie: esperar que uno termine de

acceder para que otro pueda usarlo.– De forma asincrónica mediante polling o

select.– De forma sincrónica creando procesos

separados por cada llamada IO.

Page 6: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

6

Beneficios de concurrencia

• Separar la Interfaz Usuario (IU) del core en dos procesos distintos, permite que la IU continúe respondiendo al usuario mientras en el otro hilo se realizan operaciones que demandan mucho tiempo de ejecución.

• Se busca que los servidores sean concurrentes. – Esto tradicionalmente se soluciona con fork ( ). – En algunos casos los threads pueden mejorar el uso

de memoria.

Page 7: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

7

Librería pthreadsCreacion de threads

#include <pthread.h>int pthread_create (pthread_t *thread_id, const pthread_attr_t

*attributes,void *(*thread_function)(void *), void *arguments);• Puntero a pthread_t en el cual se guarda el thread id del nuevo

thread.• Puntero a thread attribute . Detalla como interactúa el thread con

el resto del programa. Si se le pasa NULL como atributo, el thread será creado con los atributos default.

• Puntero a la función que ejecutara el thread.• Argumento del tipo void* . Lo que sea que se pase como

argumento, es pasado a la función que ejecutara el thread.

Esta función crea un thread cada vez que es llamada. Retorna un 0 en caso de éxito. En caso de error se retorna cualquier valor distinto de 0. (thread-create.c)

Page 8: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

8

Librería pthreadsTerminacion de un thread

El thread puede terminar de dos formas:

1) Con un simple return, en cuyo caso el valor que sea que se retorne será el valor de retorno del thread.

2) Mediante la función phtread_exit(). El argumento que se le pasara a esta función será el valor de retorno del thread.

Page 9: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

9

Librería pthreadsTerminacion de un thread

Existe otra forma de terminar con thread. Esto es mediante el pedido que un thread termine, acción denominada cancelación.

Para cancelar un thread se debe llamar a la función: int pthread_cancel (pthread_t thread)

El argumento a pasar es el thread id del thread que se desee cancelar.

A un thread cancelado, se le puede luego hacer un join, (de hecho es necesario hacer un join del thread cancelado para poder liberar los recursos del mismo, al menos que este haya sido detached).

Page 10: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

10

Paso de datos a un thread

Dado que el tipo de argumento es void*, no se puede pasar gran cantidad de datos de forma directa.

Se suele pasar como argumento un puntero a algún tipo de estructura o array de datos. (Ver código de ejemplo. Thread2.c).

En el código que se acaba de ver, el programa principal muere antes que los threads. Si esto ocurre, el kernel se encarga de realocar memoria mientras los otros threads la utilicen. Sin embargo la forma correcta de trabajar es asegurarse que esto no ocurra nunca.

Page 11: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

11

Librería pthreadsSincronización entre threads

Se dispone de tres tipos de sincronización:

1- Mutexes. Asegura un acceso exclusivo por el thread a determinadas variables.

2- Joins. Hace que el thread espere a que otros threads completen su tarea.

3- Variables condicionales. Son aquellas cuyo tipo es pthread_cond_t.

Page 12: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

12

Librería pthreadsJoins

int pthread_join(pthread_t thread, void **value_ptr);

El uso de esta función provee una solución para forzar al main a esperar a que uno o varios de sus threads termine antes de finalizar el proceso main.

Argumentos:

1) pthread_t thread: thread id del thread que se desea esperar

2) void **value_ptr: esta variable recibe el valor de retorno del thread cuando finaliza. Ver codigo de ejemplo (thread3.c)

Si el segundo argumento no es NULL, el valor retornado por el thread será almacenado en esta ubicación. Ver codigo ejemplo (thread 4.c)

Page 13: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

13

Librería pthreadsSincronización y zonas críticas

Al compartir el mismo espacio de memoria…

Thread 1 Thread 2

a = data; b = data;

a++; b--;

data = a; data = b;

Si este código es ejecutado de forma serial (thread1, thread2) no hay problema, sin embargo los threads se ejecutan de forma aleatoria.

Page 14: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

14

Librería pthreadsSincronización y zonas críticas

Thread 1 Thread 2a = data;

b = data;a++;

b--;data = a;

data = b;Como resultado quedaría que data = data-1!!!Para eliminar este riesgo, es necesario operar de manera

atómica, es decir de forma indivisible e ininterrumpible.

Page 15: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

15

Librería pthreadsSincronización y zonas críticas

La solución es tener funciones que bloqueen a los threads; si otro thread esta accediendo a la misma información.

Para esto se utilizaran los mutex…..

Page 16: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

16

Librería pthreadsMutexes

Mutex: Mutual Exclusion.• Son utilizados para serializar recursos

compartidos.• Son una forma especial de generar que

alguna porción de código sea atómica. • Solo un thread puede estar lockeado con

el mismo mutex, el segundo thread que desee lockearse deberá esperar a que el primero se delockee.

Page 17: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

17

Librería pthreadsMutexes. Creación

• Se debe crear una variable del tipo pthread_mutex_t, esta identificara al mutex que se este utilizando.

• Para inicializar un mutex se debe llamar a la función:

int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);

1) Puntero a la variable anteriormente mencionada

2) Son los atributos que tendrá el mutex, en el caso de ser NULL, los atributos serán aquellos que están por default.

• Declaración e inicialización:

pthread_mutex_t mutex;

pthread_mutex_init (&mutex,NULL);

Page 18: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

18

Librería pthreadsMutexes. Lock & Unlock

• Si un thread desea lockearse, simplemente deberá llamar a la función:int pthread_mutex_lock(pthread_mutex_t *mutex);Si el mutex esta siendo usado por otro thread, esta función bloquea la ejecución y retornara únicamente cuando el mutex sea liberado por el otro thread.

• Para delockear un mutex, simplemente se deberá llamar a la función:int pthread_mutex_unlock(pthread_mutex_t *mutex);Esta función deberá ser llamada siempre por el thread que lockeo al mutex.

Mutex1.c

Page 19: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

19

Librería pthreadsMutexes. Locks no bloqueantes

• En algunos casos es conveniente que el thread no quede bloqueado hasta que el mutex sea liberado por otro thread. Para esos casos existe la función:

int pthread_mutex_trylock(pthread_mutex_t *mutex);

Si el mutex no esta siendo usado por otro thread, entonces se lockea y la función retorna cero. En caso contrario, no se bloquea sino que simplemente la función retorna el código de error EBUSY. Se deberá intentar mas tarde.

Page 20: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

20

Demonios

Page 21: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

21

DemoniosSe trata de procesos que se caracterizan porque se ejecutan haciendo

que su proceso padre sea el proceso init, cuyo identificador de proceso es el 1, y NO tienen como terminales asociados de entrada y salida la pantalla y el teclado respectivamente.

Los procesos normales usan la terminal, dejandola bloqueada para otros usos hasta que el proceso finalice. Esta situacion no es deseable para algunos tipos de aplicaciones, como aquellos que mantienen una sesion para controlar un dispositivo en tiempo real 24 horas al dia. En estos casos no es logico tener una terminal bloqueada, sin mencionar que alguien por error presione las teclas Ctrl-C y por error termine el programa.

Un proceso para convertirse en demonio deben realizar dos tareas:– Independizarse del padre y "engancharse" del init.– Independizarse del terminal.

Page 22: Ing Florencia Ferrigno Tecnicas Digitales 3 1 Threads.

Ing Florencia Ferrigno Tecnicas Digitales 3

22

Demonios

• setsid(): pertenece al header unistd.h. Esta funcion permite independizarse de la terminal. De esta forma cuando el programa se ejecute no quedara bloqueada la terminal. Esta funcion crea una nueva sesion para el proceso que la llame, sin el control de la tty.

• chdir(path): pertenece al mismo header. Cambia el directorio al directorio que se le pasa como argumento. No es imperioso para la creacion de un daemon pero sirve para asegurarse que el mismo trabajara en el directorio de trabajo deseado. demonio.c integ1.c