crisis.c. La
correcta compilación de dicho programa, producirá un
fichero ejecutable, cuyo nombre será obligatoriamente
crisis. Respetad las mayúsculas/minúsculas
de los nombres, si las hubiere.
crisis n_max_procs [velocidad]
n_max_procs es el número máximo de
procesos que puede llegar a haber en cada momento de esa
ejecución de la práctica (incluido el padre).
Dicho argumento
es un número entero comprendido entre 3 y 33.
El segundo argumento es opcional y podrá valer
normal o veloz. Si no se especifica
este argumento, se entiende que su valor es normal.
La diferencia estriba en que, a velocidad veloz, no se
debe ejecutar ninguna pausa por parte de los procesos,
aunque se indiquen en el enunciado. Esto es, a esa velocidad,
no se invoca a sleep nunca.
. .---. .
. Matriz(PADRE) ____X P X____ .
. / '---' \ .
. / | \ .
. / | \ .
. .---. .---. .---. .
. Filiales X H X X H X X H X .
. '---' '---' '---' .
. | / \ .
. | / \ .
. .---. .---. .---. .
. X N X X N X X N X Subfiliales.
. '---' '---' '---' .
n_max_procs procesos.
sleep para ello. Si estamos en el modo veloz,
no hace nada.
SIGTERM de modo que cuando se mata a un proceso
con ella, antes de morir, envía señales
SIGTERMs a sus descendientes. El proceso
habrá tenido la precaución de guardar el
PID de sus hijos cuando hizo fork para
crearlos.
lockf para bloquear el fichero
mientras trabajemos con él.
V(1234) M(1234)Respetad este formato exactamente, pues es posible que se use un programa de corrección automática.
printf
no interfiera con la salida de los procesos, es importante
usar write para la salida por pantalla en su lugar.
system, salvo indicación explícita en
el enunciado de la práctica.
pauses.
srand y
rand. Hacedlo de modo que
varíen los números al azar
en cada ejecución.
wait sin bloquearse.
Aunque hay más posibles soluciones.
sleep() o
similares para sincronizar los procesos. Hay que
usar otros mecanismos.
pause().
Salvo en bucles infinitos de pauses,
su uso puede estar mal. Mirad la solución a la
práctica
propuesta en la sesión quinta acerca de él o el
siguiente LPE.
lseek el resto lo
ve movido. Este efecto secundario hace que el
siguiente código sea erróneo para
tratar de bloquear el fichero:
lseek(fd,0,SEEK_SET); lockf(fd,F_LOCK,0);La razón es que entre las dos instrucciones se puede perder la CPU y otro proceso nos puede mover el puntero que nosotros pensamos que está al principio. La solución pasa por no usar los descriptores heredados sino que cada hijo, al nacer haga algo similar a:
case 0: /* COdigo del hijo */ close(fd); // Cerramos el descriptor heredado fd=open(... // Lo volvemos a abrir
open
que hace el hijo no puede llevar O_TRUNC.
Si lo lleva, cuandoquiera que nazca un hijo, borrará
el fichero pudiendo pillar justo antes de una lectura,
que no leería nada. Lo debe abrir solamente con
el flag O_RDWR