Prácticas de Sistemas operativos David Arroyo Guardeño Escuela Politécnica Superior de la Universidad Autónoma de Madrid Cuarta semana: Hilos 1 Cronograma semanal 2 Entregas 3 Introducción Ejemplo 1 Ejemplo 2 Ejemplo 3 4 Referencias Segunda práctica 1 2 Hilos: ejercicios 3 y 4 Señales: ejercicios 6, 8 y 10 ☠☠ Jueves 5 de marzo Entregas ☠ Ejercicio3 ☠ Ejercicio 4 ¿Qué son los hilos? 3 Como los procesos → ejecución concurrente de múltiples tareas 3 Un proceso puede contener múltiples hilos 7 Todos se ejecutan independientemente 7 Comparten la misma memoria global 1 2 3 Datos inicializados Datos sin inicializar Espacio de direcciones # include # include # include # include <p t h r e a d . h> <s t d i o . h> < s t d l i b . h> <s t r i n g . h> # define NUM HILOS 5 int I = 0; void ∗ f u n c i o n h i l o ( void ∗ i d ) { int i ; f o r ( i =0; i <50; i ++) { p r i n t f ( ” H i l o %d : i=%d , I=%d\n ” , ∗ ( i n t ∗ ) i d , i , I ++) ; } pthread exit ( id ) ; } main ( ) { int h; p t h r e a d t h i l o s [ NUM HILOS ] ; i n t i d [ NUM HILOS ] = { 1 , 2 , 3 , 4 , 5 } ; int error ; int ∗salida ; f o r ( h =0; h < NUM HILOS ; h++) { e r r o r = p t h r e a d c r e a t e (& h i l o s [ h ] , NULL , f u n c i o n h i l o ,& i d [ h ] ) ; i f ( error ){ f p r i n t f ( s t d e r r , ” E r r o r %d : %s\n ” , e r r o r , s t r e r r o r ( e r r o r ) ) ; e x i t ( −1) ; } } f o r ( h =0; h<NUM HILOS ; h++) { e r r o r = p t h r e a d j o i n ( h i l o s [ h ] , ( void ∗ ∗ )& s a l i d a ) ; i f ( error ) f p r i n t f ( s t d e r r , ” E r r o r %d : %s\n ” , e r r o r , s t r e r r o r ( e r r o r ) ) ; else p r i n t f ( ” H i l o %d terminado \n ” ,∗ s a l i d a ) ; } } Ejemplo 1 3 Si cambio el valor de i en un hilo, ¿cambia para el resto? 3 Si cambio el valor de j en un hilo, ¿cambia para el resto? ☠ Comparar con el último ejemplo de la segunda semana Problemas en la gestión de procesos: necesidad de hilos 3 Es difı́cil compartir información entre procesos 3 La generación de procesos mediante fork() es cara computacionalmente # include <s t d i o . h> # include <p t h r e a d . h> # include <s t r i n g . h> void ∗ m i h i l o ( void ∗ arg ) { p r i n t f ( ”my i d i s %l d \n ” , ( long ) p t h r e a d s e l f ( ) ) ; } main ( ) { pthread t t i d ; int error ; e r r o r = p t h r e a d c r e a t e (& t i d , NULL , m i h i l o , NULL ) ; i f ( error ) f p r i n t f ( s t d e r r , ” E r r o r %d : %s\n ” , e r r o r , s t r e r r o r ( e r r o r ) ) ; / ∗ e r r o r = p t h r e a d j o i n ( p t h r e a d s e l f ( ) ,NULL ) ; i f ( error ) f p r i n t f ( s t d e r r , ” E r r o r %d : %s\n ” , e r r o r , s t r e r r o r ( e r r o r ) ) ; ∗ / e r r o r = p t h r e a d j o i n ( t i d , NULL ) ; i f ( error ) f p r i n t f ( s t d e r r , ” E r r o r %d : %s\n ” , e r r o r , s t r e r r o r ( e r r o r ) ) ; p r i n t f ( ” main t h r e a d i d %l d , new t h r e a d i d %l d . \ n ” , ( long ) p t h r e a d s e l f ( ) , ( long ) t i d ) ; } ☠ ¿Qué pasa al quitar el comentario que hay en la función main? # include <s t d i o . h> # include < s t d l i b . h> # include <s t r i n g . h> # include <u n i s t d . h> # include <p t h r e a d . h> void ∗ s l o w p r i n t f ( void ∗ arg ) { char ∗msg ; int i ; msg = ( char ∗ ) arg ; f o r ( i = 0 ; i < s t r l e n ( msg ) ; i ++ ) { p r i n t f ( ” %c ” , msg [ i ] ) ; f f l u s h ( stdout ) ; usleep (1000000) ; } p t h r e a d e x i t ( NULL ) ; } i n t main ( i n t argc , char ∗ argv [ ] ) { p t h r e a d t h1 ; p t h r e a d t h2 ; char ∗ h o l a = ” Hola ” ; char ∗mundo = ” Mundo ” ; p t h r e a d c r e a t e (&h1 , NULL , s l o w p r i n t f , ( void ∗ ) h o l a ) ; p t h r e a d c r e a t e (&h2 , NULL , s l o w p r i n t f , ( void ∗ ) mundo ) ; p t h r e a d j o i n ( h1 , NULL ) ; p t h r e a d j o i n ( h2 , NULL ) ; p r i n t f ( ” E l programa %s t e r m i n o c o r r e c t a m e n t e \n ” , argv [ 0 ] ) ; e x i t ( EXIT SUCCESS ) ; } Referencias ⇒ Francisco M. Márquez. Unix, Programación Avanzada. Editorial: Ra-Ma. 3a Edición. ISBN: 84-7897-603-5