Punto muerto-interbloqueo Que es interbloqueo? Un grupo de procesos permanentemente parados esperando cada uno por el otro. Ejemplo de interbloqueo Process P Process Q (1) Obtener A (5) Obtener B (2) Obtener B (6) Obtener A (3) Liberar B (7) Liberar A (4) Liberar A (8) Liberar B Posibles caminos de ejecución 5, 6, 7, 8, No problem 5, 6, 1, P blocks, pero terminará 5, 1, Interbloqueo inevitable 1, 5, Interbloqueo inevitable 1, 2, 5, Q blocks, pero terminará 1, 2, 3, 4, No problem
Interbloqueo
Interbloqueo Recursos reusables Puede solo se usada por un proceso al mismo tiempo. Despues del uso, puede ser reasignado a otro procesos, ( impresora, memoria, archivos, etc) En el ejemplo previo, si A = archivo, y B = tape drive, interbloqueo puede ocurrir. Puede ocurrir con localización de memoria si no se hace swapping. 200K disponible, pero ambos procesos quieren 80K, entonces hace un segundo requerimiento por 70K Recursos consumibles. Pueden ser creados o destruidos ( señales, mensajes) No límite fijo en el número de recursos Puede crear interbloqueo si ambos estan esperando cada uno por el otro.
Condiciones de interbloqueo Todos deben prepararse porque interbloqueo puede ocurrir Exclusion Mutual Solo un proceso puede tener el recurso en un momento dado de tiempo. Retener y esperar Un proceso puede retener recursos mientras otros lo estan requiriendo. No Derecho de prioridad Un recurso no puede ser forzadamente retirado de un proceso Espera circular (event) Una cadena cerrrada de procesos existe, cada uno esperando por un recurso retenido por el próximo proceso en la cadena Figure 6.5, page 273:
Ejemplo de punto puerto
Ejemplo de no punto muerto
Prevención del Interbloqueo Puede prevenir el estancamiento, al prohibir una de las condiciones Prohibir exclusión mutua Esto generalmente es no razonable Multiple read-only frecuentemente aceptables Prohibir Retener and esperar Preguntar por todos los recursos a un tiempo Puede bloquear un proceso por largo periodo de tiempo cuando este puede estar haciendo progreso Espera por los recursos no se necesita todavía Puede atar por recursos innecesarios Puede retener recursos que no se necesitan de inmediato Puede no conocer que requerir Especialmente verdad Puede requerir recursos porque ellos son necesitados en algunas circunstancias pero no siempre.
Prevención Interbloqueo Prohibir derecho preferente Toma recursos de los procesos esperando. Solo factible si el estado puede ser salvado Ejemplos: CPU, Memory No usable para archivos, impresora, etc. Prohibir espera circular Define orden linear en los items. Si requiere los items 3, 15, 6, 9, y luego 4 entonces lo debe requerir en orden 3, 4, 6, 9, 15 No puede tener espera circular porqeu un proceso no puede tener 9 y requerir 5. Puede n o ser fácil definir el orden (archivos) Puede forzar un orden extraño o torpe de requerir recursos. Puede tener qeu requerir el recurso 3 en orden de requerir 4, aun cuando 4 es necesario ahora pero 3 no es necesario hasta mucho mas tarde
Interbloqueo Prevención Permite requerimientos generales, pero hace selecciones para evitar interbloqueo. Asume que nosotros conocemos el maximo re requerimientos por cada proceso. El proceso debe especificar si necesita un maximo de: 5 A objetos, 3 B objetos, 2 C objetos. No necesita usar el máximo de requeridos Ok to establecer max=5 y solo usar 3 Puede hacer requerimientos en cualquier momento y en cualquier orden. Negación de inicio de proceso Traza las localizaciones actuales. Asume que todos los procesos pueden requerir un máximo al mismo tiempo. Solo comenzar un proceso si el no puede resultar en interbloqueo a pesar de las localizaciones.
Negación de localización de recurso Tambien llamado el algoritmo de banker Estado seguro Nosotros podemos terminar todos los procesos por alguan secuencia Ejemplo: Termina P1, P4, P2, P5, P3 Reachaza un requerimiento si este excede los procesos máxima demanda. Garantiza un requerimiento si el nuevo estado seria seguro Determinando si un estado es seguro: Encuentra un proceso Pi para el cual nosotros podemos encontrara sus máximos requerimientos. No se olvide de los recursos localizadosasignados Marque Pi como hecho, agrege su recurso al grupo de recursos disponibles. Estado es seguro si nosotros pordemos marcar todos los procesos como hecho Bloquea un proceso si los recursos no estan actualmente disponibles u otro
Ejemplo de evitar Figure 6.6, page 277 Claim Matrix: A B C P1 3 2 2 P2 6 1 3 P3 3 1 4 P4 4 2 2 Asignacion Matrix: A B C P1 1 0 0 P2 5 1 1 P3 2 1 1 P4 0 0 2 Total Recursos: 9 3 6 Disponible: 1 1 2 P1 quiere 1 A and 1 C, is it ok? P4 quiere 1 B, is it ok? Todavia requiere el proceso declarar su maximo requerimiento al principio
Detección Interbloqueo Métodos de evitar tienden a limitar acceso a los recursos. En lugar de eso, garantizar requerimientos arbitrarios y notar cuando pasa el interbloqeuo. Puede variar cuan frecuentemente nosotros chequeamos. Detección temprana versus sobrepaso de chequeos. Algoritmo (Pagina 280) Preparacion: Crear una tabla de requerimientos de procesos, asignaciones actuales. Notar los recursos disponibles. Marque los procesos sin recursos. Marque cualquier proceos cuyo requerimientos pueden ser conseguidos ( Requerimientos menor igual qeu los recursos disponibles) Incluye recursos desde ese proceso disponible este proceso puede terminar. Si múltiples procesos son disponibles, seleccione uno. Si uno de los procesos no puede ser marcado, ellos son parte del interbloqeuo.
Detection Example Figure 6.9, page 281 Requerimientos: P1 0 1 0 0 1 P2 0 0 1 0 1 P3 0 0 0 0 1 P4 1 0 1 0 1 Asignacion: A B C D E P1 1 0 1 1 0 P2 1 1 0 0 0 P3 0 0 0 1 0 P4 0 0 0 0 0 disponible 0 0 0 0 1 A B C D E MarqueP4 (nothing allocated) Marque P3, nuevo disponible: 0 0 0 1 1 No puede marcar P1 or P2, por lo tanto estan interbloqeuados
Detection Example 2 Requerimientos: A B C P1 0 0 0 P2 2 0 2 P3 0 0 0 P4 1 0 0 P5 0 0 2 Asignacion: A B C P1 0 1 0 P2 2 0 0 P3 3 0 3 P4 2 1 1 P5 0 0 2 disponible 0 0 0 Esta este sistema interbloqueado?
Recuperacion de Interbloqueo Varios enfoques posibles Aborta todos los procesos interbloqueados. Simple pero comun Respalda los procesos a un punto de chequeo salvado, despues se rearrancan. Asume que nosotros tenemos puntos de chequeo y mecansmo de reversiço. Corre riesgo de repetir el interbloqueo Asume que el interbloqueo tiene suficiente de manera que dependencias de tiempo no pasaran. Selectivamente aborta procesos hasta que el problema de interbloqeuo esta resuelto. Adelanta recursos hasta que el interbloqeuo esta roto. Debe revertir procesos a puntos de chequeo previos a adquirir el recurso clave.
Estrategia mezclada puede agrupar Recursos into clases, tiene una clase diferente de interbloqueo para cada clase Intercambio espacio Previene puntos muertos por requerimientos de todo el espacio a ser asignado de una Evitacion tambien posible Tapes/Files Evitacion puede ser efectiva aqui. Prevencion por ordenamiento de recursos tambien es posible Memoria principal Derecho preferente un buen enfoque Recursos internos (channels, etc.) Prevencion por ordenamiento de Recursos Puede usar orden lineal entre las clases
La cena de los filosofos Cinco filosofos tienen que alternativamete cenar y pensar Comparte un tenedor con un vecino Asuma que cada filosofo levanta primero el tenedo izquierdo, luego el tenedor derecho y luego come. Interbloqueo si todos comienzan a comer a la vez.
Resolviendo la cenda de los filosofos Compre mas tenedores Equivalente a incrementar los Recursos Coloca el tenedor en la mesa si el segundo tenedor esta ocupado. Puede producir bloqeuo activo si los filosofos permanecen sincronizados. Habitaciçon de los asistentes Solo deje 4 de los filosofos en el salon a un tiempo puede tener 4 filosofos en el salon pero solo uno puede comer. Filosofos zurdos Agarre los tenedores en otro orden, Primero tenedor derecho, luego el izquierdo Cualquier mezcla evitara un punto muerto. Effectivo ordenamiento linear de los tenedores.
fork() Linux Fork() returns 0 to child return child_pid to parent Parent is responsible to look after children Failure to do so can create zombies pid = wait( &status ) to explicitly wait for the child to terminate signal(sigchld, SIG_IGN) to ignore child-termination signals puede also set SIGCHLD to call a specified subroutine when a child dies
Fork() Example #include <stdio.h> #include <signal.h> void main() { int cnt = 15; int pid; char buff[100]; /* create a new process */ if ((pid = fork()) == -1) { perror("fork failed, call system manager!"); exit(1); } if (pid) { /* we are the parent, tell system to ignore child termination messages */ signal(sigchld, SIG_IGN); while (cnt--) { /* lets look for the child */ printf("the child has a pid of %d, my pid is %d\n", pid, getpid()); printf("----------------------\n"); sprintf(buff, "%s %d", "ps -aux grep ", pid); system(buff); /* execute the command */ printf("----------------------\n"); sleep(1); /* let some time pass */ } exit(0); } else { /* here is the child code */ int cnt = 8; while (cnt) { printf("[child] I'm alive...cnt = %d\n", cnt--); sleep(1); } printf("[child] Preparing to exit with status 7\n"); exit(7); /* quit */ } } /* end of program */
Linux Semaphores Key - 4 byte value for the name Create/access semaphores id = semget( KEY, Count, IPC_CREAT PERM ) id = semget( KEY, 0, 0 ) Perm = file permission bits (0666) to create only (fails if exists) use IPC_CREAT IPC_EXCL PERM Count = # of semaphores to create Working with semaphore value i = semctl( id, num, SETVAL, v ) val= semctl( id, num, GETVAL, 0 ) Deleting semaphores i = semctl( id, 0, IPC_RMID, 0 ) ipcs Program to list semaphores/etc. ipcrm sem id Program to delete a semaphore
Semaphore Operations Semaphore Structure struct sembuf { short sem_num; short sem_op; short sem_flg; } op; (semaphore ID) (change amount) (wait/don t wait) sem_flg can be 0 or IPC_NOWAIT Wait(): op.sem_op = -1 (decrement) res = semop( id, &op, 1 ) Signal(): op.sem_op = 1 (increment) res = semop( id, &op, 1 ) Can do multiple signal/wait ops res = semop( id, oparray, opcount )
Create Example #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <errno.h> #define PERM 0666 #define KEY 0x12348765 main() {int id, result; id = semget(key,1, IPC_CREAT IPC_EXCL PERM); printf("status of create = %d\n", id); if(id == -1){perror("Bad Semaphore Create"); exit(0);} /* set the value to one */ result = semctl(id,0,setval,1); if(result == -1){ perror("bad SetVal call");exit(0);} printf("semaphore created with an id of %d\n",id); }
Wait Example #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <errno.h> #define KEY 0x12348765 main() {int id, result; struct sembuf op[1]; id = semget(key,0,0); printf("status of get key = %d\n",id); if(id == -1) {perror("bad Semaphore ID fetch"); exit();} /* initialize the op data structure */ op[0].sem_num = 0; /* the first one */ op[0].sem_op = -1; /* wait until we can add 1 */ op[0].sem_flg = 0; /* no options */ /* now try to get past the semaphore */ printf("ready to test semaphore\n"); result = semop(id,op,1); if(result == -1){ perror("bad Wait"); exit();} printf("got past semaphore\n"); }
Shared Memory Create/Access Shared Memory id = shmget( KEY, Size, IPC_CREAT PERM ) id = shmget( KEY, 0, 0 ) Deleting Shared Memory i = shmctl( id, IPC_RMID, 0 ) Or use ipcrm Accessing Shared Memory memaddr = shmat( id, 0, 0 ) memaddr = shmat( id, addr, 0 ) Addr should be multiple of SHMLBA memaddr = shmat( id, 0, SHM_READONLY ) System will decide address to place the memory at shmdt( memaddr ) Detach from shared memory
Creating Shared Memory #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <errno.h> #define SIZE 512 /* shared mem buffer size */ #define PERM 0666 /* all can read write */ #define KEY 'JHL ' /* our key */ main() { int id; } id = shmget(key,size, IPC_CREAT IPC_EXCL PERM ); printf("status of create = %d\n",id); if(id == -1) perror("bad Create");
Writing Shared Memory #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <string.h> #include <errno.h> #include <stdio.h> #define SIZE 512 /* shared memory buffer size */ #define KEY 'JHL ' /* our key */ main() { } key_t key; int memoryid; char * location; /* the shmget will fail if the segment has not been created */ memoryid = shmget(key,size,0); printf("status of key retrieval = %d\n",memoryid); if(memoryid == -1) {perror("bad Key");exit();} /* we got the key now attach to the segment */ we will allow the system to chose the location (second parm) and we will want read/write access (third parm) location = (char *)shmat(memoryid,0,0); /* we want read write access */ printf("status of attach = %d\n",location); if (location == (char*)-1) {perror("bad Attach");exit();} /* memory has been attached to,now copy string into the location */ printf("enter string -> "); gets(location); printf("location contains: %s\n",location);
Unix Pipes Creates a one-way connection between processes Created using pipe() call Returns a pair of file descriptors pend[0] = read end pend[1] = write end Use dup() call to convert to stdin/stdout Example: int pend[2] pipe( pend ) fork() parent close(pend[1]) read(pend[0], ) close(pend[0]) child close(pend[0]) write(pend[1], ) close(pend[1])
Unix Pipe Example /* A simple "pipe" demo --- Author: Jerry LeVan */ #include <stdio.h> #define DATA "Sample Data Sent Through A Pipe" main() { int sockets[2], child; /* create a pipe; doing it here assures that it will be open in the child */ if(pipe(sockets) <0){ perror("opening stream socket pair"); exit(10); } if((child = fork()) == -1) /* fork the child */ perror("fork"); else if (child) { char buf[1024]; /* this is the parent */ sleep(4); /* let the child do its stuff */ close(sockets[1]); /* close "write" side */ if ( read(sockets[0],buf,1024) < 0) perror("reading message"); printf("-->%s\n",buf); /* Do you know why this works? */ close(sockets[0]); /* shut "read" side */ }else { /* this is the child. It writes to the parent */ close(sockets[0]); /* close "read" side */ if ( write(sockets[1],data,sizeof(data)) < 0) perror("writing message"); close(sockets[1]); /* close "write" side */ printf("[child] I am outa here...\n"); exit(0); } }
Unix Messages Send information (type + data) between processes Message Structure long type char text[] Functions: id = msgget( KEY, IPC_CREAT ) id = msgget( KEY, 0 ) msgctl( id, IPC_RMID ) msgsnd( id, buf, text_size, flags ) msgrcv( id, buf, max_size, flags ) Useful Flags IPC_NOWAIT MSG_NOERROR (truncate long messages to max_size)
Other Unix Synchronization Semaphores (discussed earlier) Shared Memory (discussed earlier) Signals Used to inform processes of asynchronous events Set up handler using void handler( int sig_num ) { } sig_num is signal number so one handler can respond to several signals signal( SIGxxx, handler) One-time event Must reset within handler if you want to keep handling this signal (Linux) special value for handler» SIG_IGN Ignore signal» SIG_DFL Default action Partial list (Table 6.2, page 288) SIGHUP, SIGQUIT, SIGKILL, SIGALARM, SIGUSR1, SIGCLD Send signal using kill command/call
Solaris Both Kernel and User-level calls Mutual Exclusion Lock mutex_enter() Waiting processes can busy-wait or be suspended mutex_exit() Liberar lock mutex_tryenter() Get lock if not held Condition Variables Used in conjunction with a mutex lock cv_wait() The process will release the associated mutex before waiting, reacquire it before continuing cv_signal() Wake up one thread waiting on a given condition cv_broadcast() Wake up all threads Mutex + Condition Variables can be used to implement monitors
Solaris Semaphores sema_p() tradicional Wait() sema_v() tradicional Signal() sema_tryp() Reader/Writer Lock rw_enter() Get lock as a reader or writer rw_exit() Liberar a lock rw_tryenter() Try to get a lock, but don t wait if it isn t disponible rw_downgrade() Convert a write lock to a read lock rw_tryupgrade() Try to convert a read lock into a write lock
Windows 2000 Synchronization Objects (table 6.3, page 292) Process Signals on termination Thread Signals on termination File Signal on I/O operation complete Console Input Signal on data ready File Change Notification Signal when a file system change matching a filter happens Mutex Provides mutual exclusion Semaphore Counting semaphore Event Announcement a system event has happened Waitable Timer Counter that records the passage of time