Prácticas de Sistemas operativos David Arroyo Guardeño Escuela Politécnica Superior de la Universidad Autónoma de Madrid Octava semana: semáforos
1 Cronograma semanal 2 Introducción 3 Ejemplo 1 4 Ejemplo 2 5 Ejemplo 3 6 Referencias
Tercera práctica 1 Memoria compartida: ejercicio 2 2 Semáforos: ejercicios 4 y 5 3 Ejercicio final: ejercicios 6 y 7 (opcional) Jueves 3 abril
Semáforos Mecanismo para implementar sincronización Número entero: si se intenta hacer menor que cero, el proceso queda en espera Biblioteca sem.h man semget semop semctl
main ( ) { i n t sem id, i ; struct sembuf sem oper ; union semun{ i n t val ; struct semid ds semstat ; unsigned short array ; arg ; sem id = semget (SEMKEY,N SEMAFOROS, IPC CREAT IPC EXCL SHM R SHM W) ; i f ( sem id== 1){ p e r r o r ( semget. ) ; e x i t ( errno ) ; i f (N SEMAFOROS<2){ f p r i n t f ( s t d e r r, El numero de semaforos ha ser mayor que dos\n ) ; e x i t ( 0 ) ; arg. array = ( unsigned short ) malloc ( sizeof ( short ) N SEMAFOROS) ; for ( i =0; i<n SEMAFOROS; i ++) arg. array [ i ] = 1; semctl ( sem id,n SEMAFOROS,SETALL, arg ) ; sem oper. sem num = 0; sem oper. sem op = 1; sem oper. sem flg = SEM UNDO; semop ( sem id,& sem oper, 1 ) ; sem oper. sem num = 1; sem oper. sem op = 1; semop ( sem id,& sem oper, 1 ) ; semctl ( sem id,n SEMAFOROS,GETALL, arg ) ; p r i n t f ( Los valores de l o s semaforos son [%d, arg. array [ 0 ] ) ; for ( i =1; i<n SEMAFOROS; i ++) p r i n t f (,%d, arg. array [ i ] ) ; p r i n t f ( ]\n ) ; semctl ( sem id,n SEMAFOROS, IPC RMID, 0 ) ; f r e e ( arg. array ) ;
Ejemplo 2: productor #define SEMKEY 76102 union semun { i n t val ; struct semid ds buf ; ushort array ; struct seminfo buf ; ; main ( ) { k e y t key = SEMKEY; i n t sem id ; union semun arg ; enum {NS,EO; s t a t i c struct sembuf sig = {0,1,SEM UNDO, wait={0, 1,SEM UNDO; s t a t i c ushort s t a r t v a l u e [ 2 ] = {0,0; i n t clock =3; i f ( ( sem id = semget ( key, 2, IPC CREAT 0666) ) == 1){ p e r r o r ( c o n t r o l : semget. ) ; e x i t ( 1 ) ; arg. array = start value ; i f ( semctl ( sem id, 0,SETALL, arg ) == 1){ p e r r o r ( c o n t r o l : semctl i n i c i a l i z a c i o n. ) ; e x i t ( 2 ) ; p r i n t f ( c o n t r o l : Estoy l i s t o.\n ) ; while ( clock ){ s i g. sem num = NS; i f ( semop ( sem id,& sig, 1 ) == 1){ p e r r o r ( c o n t r o l : semop s i g n a l. ) ;
main ( ) {... Ejemplo 2: productor arg. array = start value ; i f ( semctl ( sem id, 0,SETALL, arg ) == 1){ p e r r o r ( c o n t r o l : semctl i n i c i a l i z a c i o n. ) ; e x i t ( 2 ) ; p r i n t f ( c o n t r o l : Estoy l i s t o.\n ) ; while ( clock ){ s i g. sem num = NS; i f ( semop ( sem id,& sig, 1 ) == 1){ p e r r o r ( c o n t r o l : semop s i g n a l. ) ; e x i t ( 3 ) ; wait. sem num = EO; i f ( semop ( sem id,& wait, 1 ) == 1){ p e r r o r ( c o n t r o l : semop wait. ) ; e x i t ( 4 ) ; p r i n t f ( c o n t r o l : La c a r r e t e r a este oeste esta a b i e r t a.\n ) ; sleep ( 1 ) ; clock ; i f ( semctl ( sem id, 0, IPC RMID, 0 ) == 1){ perror ( control : semctl remove. ) ; e x i t ( 5 ) ;
... main ( ) { k e y t key = SEMKEY; i n t semid ; i n t car num =1; Ejemplo 2: consumidor s t a t i c struct sembuf sig ={0,1,SEM UNDO, wait={0, 1,SEM UNDO; enum {NS,EO; i f ( ( semid = semget ( key, 2, IPC CREAT 0666) ) == 1){ p e r r o r ( coche : semget. ) ; e x i t ( 1 ) ; while ( 1 ){ wait. sem num = NS; i f ( semop ( semid,& wait, 1 ) == 1){ p e r r o r ( coche : semop wait. ) ; e x i t ( 2 ) ; p r i n t f ( coche : La c a r r e t e r a norte sur esta a b i e r t a.\n ) ; sleep ( 1 ) ; p r i n t f ( coche : Coche %d paso.\n, car num ++) ; s i g. sem num = EO; i f ( semop ( semid,& sig, 1 ) == 1){ p e r r o r ( coche : semop s i g n a l. ) ; e x i t ( 3 ) ;
Ejemplo 3: productor #define SHMKEY 6723 #define SEMKEY 7543 #define NUMPEDIDOS 10 union semun { i n t val ; struct semid ds buf ; ushort array ; struct seminfo buf ; ; main ( ) { k e y t key= SHMKEY; k e y t key2 = SEMKEY; i n t shmid ; i n t sopa = 0; i n t orden = NUMPEDIDOS; i n t sem id ; union semun arg ; enum {COOK, PICK; s t a t i c struct sembuf cook = {0,1,SEM UNDO, pick = {0, 1,SEM UNDO; s t a t i c ushort s t a r t v a l u e [ 2 ] = {0,0; i f ( ( sem id = semget ( key2, 2, IPC CREAT 0666) ) == 1){ p e r r o r ( cocina : semget. ) ; e x i t ( 1 ) ; arg. array = start value ; i f ( semctl ( sem id, 0,SETALL, arg ) == 1){ p e r r o r ( cocina : semctl i n i c i a l i z a c i o n. ) ; e x i t ( 2 ) ;
Ejemplo 3: productor main ( ) {... i f ( ( shmid = shmget ( key,50,0600 IPC CREAT ) ) == 1) { p e r r o r ( cocina : shmget ) ; e x i t ( 1 ) ; sopa = ( i n t )shmat ( shmid, ( char ) 0,0) ; i f ( sopa == ( i n t ) 1) { p e r r o r ( cocina : shmat ) ; e x i t ( 2 ) ; p r i n t f ( Cocinero : He empezado a hacer l a sopa.\n ) ; while ( orden ) { sleep ( 1 ) ; ( sopa ) ++; cook. sem num = COOK; i f ( semop ( sem id,& cook, 1 ) == 1){ p e r r o r ( cocina : semop cook. ) ; e x i t ( 3 ) ; pick. sem num = PICK ; i f ( semop ( sem id,& pick, 1 ) == 1){ p e r r o r ( c o n t r o l : semop wait. ) ; e x i t ( 4 ) ; p r i n t f ( Oido cocina... \ n ) ; orden ; p r i n t f ( Cocinero : Se acabo el tiempo. He preparado %d platos de sopa. Quedan %d sin recoger.\n,numpedidos, sopa ) ; shmctl ( shmid, IPC RMID, ( struct shmid ds ) 0) ; i f ( semctl ( sem id, 0, IPC RMID, 0 ) == 1){ p e r r o r ( cocina : semctl remove. ) ; e x i t ( 5 ) ; e x i t ( 0 ) ;
void manejador ( ) { e x i t ( 0 ) ; main ( ) { void signal catcher ( ) ; k e y t key = SHMKEY; key t key sem = SEMKEY; i n t shmid ; i n t sopa ; Ejemplo 3: consumidor i n t sem id ; s t a t i c struct sembuf cook ={0,1,SEM UNDO, pick={0, 1,SEM UNDO; enum {COOK, PICK; i f ( ( sem id = semget ( key sem, 2, IPC CREAT 0666) ) == 1){ p e r r o r ( camarero : semget. ) ; e x i t ( 1 ) ; sigset (SIGALRM, manejador ) ; alarm ( 30) ; i f ( ( shmid = shmget ( key,50,ipc CREAT 0600) ) == 1) { p e r r o r ( shmget ) ; e x i t ( 1 ) ; i f ( ( sopa = ( i n t )shmat ( shmid, 0, 0 ) ) ==( i n t ) 1) { p e r r o r ( shmat ) ; e x i t ( 2 ) ; while ( 1 ){ pick. sem num = COOK; i f ( semop ( sem id,& pick, 1 ) == 1){ p e r r o r ( camarero : semop pick. ) ; e x i t ( 2 ) ; ( sopa ) ; p r i n t f ( Camarero : p l a t o recogido\n ) ; sleep ( rand ( ) %2+1) ; p r i n t f ( Camarero : un nuevo p l a t o de sopa, cocina!!! \ n ) ; cook. sem num = PICK ; i f ( semop ( sem id,& cook, 1 ) == 1){ p e r r o r ( camarero : semop cook. ) ; e x i t ( 3 ) ;
Referencias Francisco M. Márquez. Unix, Programación Avanzada. Editorial: Ra-Ma. 3 a Edición. ISBN: 84-7897-603-5