Hilos - Universidad Pontificia Bolivariana

Anuncio
THREADS
Sistemas Distribuidos
Alvaro Ospina Sanjuan
Universidad Pontificia Bolivariana
Medellín 2010
Threads - procesos livianos

Permiten hacer invocaciones de métodos para que se
ejecuten en forma paralela al programa principal.

Permite tener varias ejecuciones dentro del mismo código por
lugares diferentes, pero dentro del mismo proceso.

Comparten datos con el programa principal

Poseen su propio contador de programa, registros y pila.

Compiten con el programa principal por el procesador.

Tienen cambios de contexto más rápidos que los procesos.

Si el programa principal termina, mata a todos los threads.
pthreads
POSIX:"Programmers Operating System Interface for
UNIX" - Interfaz para programación usando "threads"
y lenguaje C en UNIX, establecido en el estándar IEEE
POSIX 1003.1c.
La implementación de pThreads requiere:
Un archivo de encabezado llamado pthread.h
Una biblioteca de programación llamada libpthread.a
Estandar para threads POSIX
(Portable Operating System Interface
for UNIX)

int pthread_create( pthread_t *tid,
const pthread_attr_t *attr,
void * (*routine)( void*),
void *arg)

pthread_exit(): termina el hilo sin terminar el proceso

pthread_join(): Esperar a que el thread termine.

Pthread_self: Id del thread actual.

Compilación: gcc –o ejecutable
-lpthread
fuente.c
Hilos

pthread_t * es un puntero a un identificador de thread.

pthread_attr_t * son los atributos de creación del hilo. Hay varios
atributos posibles, como por ejemplo la prioridad. Se puede pasar NULL,
con lo que el hilo se creará con sus atributos por defecto, generalmente
es suficiente.

void *(*)(void *) una función que admite un puntero void * y que
devuelve void *. Esta función es la que se ejecutará como un hilo aparte.
El hilo terminará cuando la función termine o cuando llame a la función
pthread_exit() (o que alguien lo mate desde otra parte del código). Es
bastante habitual hacer que esta función se meta en un bucle infinito y
quede suspendida en un semáforo o a la espera de una señal para hacer
lo que tenga que hacer y volver a quedar dormida.

void * es el parámetro que se le pasará a la función anterior cuando se
ejecute en el hilo aparte. De esta manera nuestro programa principal
puede pasar un único parámetro (que puede ser cualquier cosa, como una
estructura compleja) a la función que se ejecutará en el hilo. La función
Creación de Hilos
#include <pthread.h>
...
pthread_t pthreadID;
int param;
...
void * Thread_routine(void *arg) {
...
}
pthread_create(
&pthreadID,
//Identificador numérico
NULL,
//Atributos ("joinable", etc.)
Thread_routine, //Rutina funcional del "thread"
(void *) param );
//Argumentos
Destrucción de Hilos
•
Los "threads" pueden eliminarse por alguno de
los siguientes eventos:
–
–
•
Ejecución de pthread_exit(status)
Ejecución, por parte de otro "thread" de
pthread_cancel(...)
–
Finalización del proceso dueño.
–
Finalización de la rutina principal (main(...)).
Hay que considerar que cuando un "thread" es
terminado abruptamente, sus apuntadores no son
eliminados.
Sincronización Hilos
•
•
La vinculación ("joinning") es un procedimiento
común para la sincronización de "threads".
Cuando se ejecuta una vinculación, el "thread"
invocador se bloquea hasta que el otro
especificado termine.
–
pthread_join(threadID,&status)
–
pthread_detach(threadID,&status)
Ejercicios de threads

Ejercicio 1

Ejercicio 2

Ejercicio 3
Ejercicios calculo de pi
Solución es escalable
Ejercicios de threads
•
•
Vamos a realizar división de trabajo
Para este caso, de los m intervalos vamos a asignar n a
cada “thread” (siendo n=m/cantidad_threads)
Solución es escalable
Ejercicio 1
#include<pthread.h>
#include<stdio.h>
#include<string.h>
// Funcion que ejecuta el hilo
void * function_thr(char *cadena){
sleep(5);
printf("Hilo %d:mi cadena es: %s\n",pthread_self,cadena);
pthread_exit(pthread_self);
}
int main(void){
pthread_t id;
printf("Creando thread ...\n");
char *cadena=strdup("soy un thread");
pthread_create(&id, NULL,(void *)&function_thr, (void *) cadena);
printf("Ppal: Esperando que el thread termine..\n");
pthread_join(id,NULL);
printf("Ppal: el thread termino\n");
return 0;
}
Ejercicio 2
#include<pthread.h>
#include<stdio.h>
#include<string.h>
//parametros de la funcion
struct parametros{
int num;
char *cadena;
};
// Funcion con varios parametros que llegan en un puntero a estructura
void * function_thr(struct parametros *p){
printf("Hilo:numero %d y mi cadena es: %s\n",p->num,p->cadena);
pthread_exit(pthread_self);
}
int main(void){
//se llena la estructura de parametros del metodo
struct parametros param;
param.cadena=strdup("soy un thread");
param.num=15;
// se lanza el thread
pthread_t id;
pthread_create(&id, NULL,(void *)&function_thr, (void *) &param);
printf("Ppal: Esperando que el thread termine..\n");
pthread_join(id,NULL);
printf("Ppal: el thread termino");
return 0;
}
Ejercicio 3
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_THREADS 3 // cantidad de threads que se lanzan
struct parametros{
int num;
char *cadena;
};
pthread_t tabla_thr[MAX_THREADS]; //arreglo con id de los threads
struct parametros param[MAX_THREADS]; //arreglo con los parametros de los threads
//funcion que recibe un puntero a la estructura de parametros del thread
void * function_thr(struct parametros *p){
printf("Hilo:numero %d y mi cadena es: %s\n",p->num,p->cadena);
pthread_exit(pthread_self);
}
int main(void){
printf("Creando threads ...\n");
int i;
for(i=0;i<MAX_THREADS;i++){
param[i].cadena=strdup("soy un thread");
param[i].num=i;
pthread_create(&tabla_thr[i], NULL,(void *)&function_thr, (void *) &param[i]);
}
printf("Ppal: Esperando que los threads terminen..\n");
for(i=0; i<MAX_THREADS;i++){
pthread_join(tabla_thr[i], NULL);
printf("Ppal: el thread %d termino\n",i);
}
printf("Todos terminaron...\n");
return 0;
Descargar