Elementos sistema operativo Se examinarán los componentes más comunes dentro del S.O. En particular se verán los siguientes elementos. • El núcleo • La llamada de sistema • El shell El kernel o núcleo • Lugar donde residen todos los módulos del S.O. • Generalmente solo representa una pequeña porción del código del S.O. • Kernel generalmente se encuentra en memoria principal • Funciones • • • • • • • Procesamiento de interrupciones Creación/destrucción de procesos Sincronización de procesos Soporte de actividades de E/S Soporte de actividades de asignación de memoria Soporte de actividades de desasignación de memoria Soporte a actividades con archivos Llamadas de sistema El shell Modelo capas Unix Semáforos Semáforos Binarios • Solo puede tomar dos valores: 0 ó 1 • Generalmente se inicializan con un valor de 1. • Son usados por dos o más procesos para garantizar que sólo uno puede entrar en sección crítica. • Antes de entrar en sección crítica un proceso ejecuta un P(S) y un V(S) antes de salir de ella. • La variable de tipo semáforo se llama entrar y es inicializada en 1. Cada proceso tiene la estructura siguiente: #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #define SEM_PADRE 1 #define SEM_HIJO 0 main(int argc, char *argv[ ]) { Int i=10, semid, pid; struct sembuf operacion; Número de semáforos key_t llave; /*Peticion de un identificador con dos semaforos*/ llave=ftok(argv[0],’K’); If((semid=semget(llave, 2 ,IPC_CREAT│0600))==-1) { perror(“semget”); exit(-1); } /* Inicialización de los semáforos */ /*Cerramos el semáforo del proceso hijo */ semctl(semid, SEM_HIJO, SETVAL,0); /*abrimos el semáforo del proceso padre */ semctl(semid, SEM_PADRE, SETVAL,1); /*creación del proceso hijo */ If((pid=fork()) == -1) { perror(“fork”); exit(-1); } else if(pid==0) { /*código del proceso hijo */} while(i) { /* cerramos el semáforo del proceso hijo */ operacion.sem_num=SEM_HIJO; operacion.sem_op=-1; operacion.sem_flg=0; semop(semid, &operacion,1); P(S) hijo printf(“PROCESOS HIJO: %d \n”,i--); /*Abrimos el semáforo del proceso padre */ operacion.sem_num=SEM_PADRE; V(S) padre operacion.sem_op=1; semop(semid,&operación,1); printf(“PROCESO PADRE: %d \n”,i--); } /*Borrado del semáforo */ semctl(semid,0,IPC_RMID,0); } else { /*codigo del proceso padre */ operación.sem_flg=0; while(i){ operacion.sem_num=SEM_PADRE; operacion.sem_op= -1; semop(semid,&operacion,1); printf(“PROCESO PADRE: %d \n”,i--); P(S) padre /*Abrimos el semáforo del proceso hijo*/ operacion.sem_num=SEM_HIJO; operacion.sem_op= 1; semop(semid,&operacion,1); } /*Borrado del semáforo */ semctl(semid,&operacion,1); } } V(S) hijo Inicialización P11-h00 P10-h01 Inicialización P00-h11 P01-h10 sem_op > < 0 acción sem_op+ v. semáforo |sem_op|>v. semaforo liberado bloqueado hasta v. semaforo = |sem_op| v. semaforo- |sem_op| liberado bloqueado hasta v.semaforo=0, si ya es cero la llamada vuelve inmediatamente Padre Valor inicio 0 Rojo 1 Verde Zona critica 1 hijo 0 Padre (i=10) -1 (Sp)1-1=0 Printf(i) 1 (Sh)0+1=1 Hijo -1 (Sh)1-1=0 Printf(i) 1 (Sp)0+1=1 Padre (i=9) -1 (Sp)1-1=0 Printf(i) 1 (Sh)0+1=1 Hijo -1 (Sh)1-1=0 Printf(i) 1 (Sp)0+1=1 Padre (i=8) -1 (Sp)1-1=0 Printf(i) 1 (Sh)0+1=1 Hijo (i=8) -1 (Sh)1-1=0 Printf(i) 1 (Sp)0+1=1 ... ... ... ... (i=10) (i=9) Padre (i=1) -1 (Sp)1-1=0 Printf(i) 1 (Sh)0+1=1 Hijo -1 (Sh)1-1=0 Printf(i) 1 (Sp)0+1=1 (i=1)