Sie sind auf Seite 1von 7

ALGORITMO DE DEKKER

El algoritmo de Dekker (alternancia estricta): es un algoritmo de programacin concurrente para


exclusin mutua, que permite a dos procesos o hilos de ejecucin compartir un recurso sin
conflictos. Fue uno de los primeros algoritmos de exclusin mutua inventados, implementado por
Edsger Dijkstra.
Si ambos procesos intentan acceder a la seccin crtica simultneamente, el algoritmo elige un
proceso segn una variable turno. Si el otro proceso est ejecutando en su seccin crtica, deber
esperar su finalizacin.
Existen cinco versiones del algoritmo Dekker, teniendo ciertos fallos los primeros cuatro. La
versin 5 es la que trabaja ms eficientemente, siendo una combinacin de la 1 y la 4.
Primer algoritmo
Garantiza la exclusin mutua, pero su desventaja es que acopla los procesos fuertemente, esto
significa que los procesos lentos atrasan a los procesos rpidos.
Repeat
Hace_Cosas();
While turno =2 Do;
REGION_CRITICA();
turno = 2;
Hace_mas_cosas();
Until Fin
Repeat
Hace_Cosas();
While turno = 1 Do;
REGION_CRITICA();
turno = 1;
Hace_mas_cosas();
Until Fin

Segundo algoritmo
Problema interbloqueo. No existe la alternancia, aunque ambos procesos caen a un mismo estado
y nunca salen de ah.
PROGRAMA DOS;
Variables
P1QE, P2QE: Bool;
Inicializacin
P1QE = false;
P2QE = false;
Repeat
Hace_Cosas();
P1QE = true;
While P2QE Do;
REGION_CRITICA();
P1QE = False;
Hace_mas_cosas();
Until Fin
repeat
Hace_Cosas();
P2QE = true;
While P1QE Do;
REGION_CRITICA();
P2QE = False;
Hace_mas_cosas();
Until Fin

Tercer algoritmo
Colisin regin crtica no garantiza la exclusin mutua. Este algoritmo no evita que dos procesos
puedan acceder al mismo tiempo a la regin crtica.
PROGRAMA TRES;
Variables
P1A, P2A: Bool;
Inicializacin
P1A = false;
P2A = false;
Repeat
Hace_Cosas();
While P2A Do;
P1A = true;
REGION_CRITICA();
P1A = False;
Hace_mas_cosas();
Until Fin
Repeat
Hace_Cosas();
While P1A Do;
P2A = true;
REGION_CRITICA ();
P2A = False;
Hace_mas_cosas();
Until Fin
Cuarto algoritmo
Postergacin indefinida. Aunque los procesos no estn en interbloqueo, un proceso o varios se
quedan esperando a que suceda un evento que tal vez nunca suceda.
PROGRAMA CUATRO;
Variables
P1QE, P2QE: Bool;
Inicializacin
P1QE = false;
P2QE = false;
Repeat
Hace_Cosas();
P1QE = true;
While P2QE Do
Begin
P1QE = false;
Delay (random());
P1QE = true;
end;
REGION_CRITICA();
P1QE = False;
Hace_mas_cosas();
Until Fin
Repeat
Hace_Cosas ();
P1QE = true;
While P2QE Do
Begin
P2QE = false;
Delay (random());
P2QE = true;
end;
REGION_CRITICA();
P2QE = False;
Hace_mas_cosas();
Until Fin

Quinto Algoritmo

El quinto algoritmo de Dekker es la versin optimizada y que no presenta problemas como las
cuatro versiones anteriores, para su estructuracin se hace una combinacin de dos algoritmos de
acuerdo al orden de prioridad de desempeo y funcionamiento de las cuatro versiones conocidas.

PROGRAMA CINCO;
Variables
P1QE, P2QE: Bool;
turno: Entero;
Inicializacin
P1QE = false;
P2QE = false;
turno = 1
Repeat
Hace_Cosas();
P1QE = true;
While P2QE Do
Begin
if(turno = 2)
Begin
P1QE = false;
Delay (random());
P1QE = true;
end;
end;
REGION_CRITICA();
turno = 2;
P1QE = False;
Hace_mas_cosas();
Until Fin
Repeat
Hace_Cosas();
P2QE = true;
While P1QE Do
Begin
if(turno = 1)
Begin
P2QE = false;
Delay (random());
P2QE = true;
end;
end;
REGION_CRITICA();
turno = 1;
P2QE = False;
Hace_mas_cosas();
Until Fin

Ejemplo:

Planteamiento:
Los n procesos llegan a la vez a la memoria (seccin crtica), o desean entrar en ella. El algoritmo
de espera activa regula la entrada de los procesos. Los procesos comparten la variable 'recurso', y
se bebe evitar que mientras un proceso est accediendo a la variable, otro proceso la est
modificando al mismo tiempo. Mediante el algoritmo de DEKKER se consigue:
Exclusin mutua con respecto al recurso
Se concede a cada proceso el acceso en un tiempo finito
Se libera el recurso en un tiempo finito
Existe espera activa
Para el programa hemos elegido que el nmero de procesos sea cuatro, aunque el nmero de
ellos puede variar a conveniencia, modificndolo en el #define.



Solucin
Para controlar el acceso al recurso disponemos de dos tipos de variable:
o n variables de cerradura (expresan la iniciativa de cada proceso para entrar en su
seccin crtica). Para el programa, dichas variables son:
entrarSC[]
Los valores que toman estas variables son:
T: El proceso quiere acceder a su seccin crtica
F: El proceso no quiere acceder a su seccin crtica
Nota: Inicialmente todas las variables cerradura toman el valor F, es decir, ningun proceso desea
acceder a su seccin crtica.
o una variable turno (variable de alternancia que permite el acceso de un proceso a
su seccin crtica). Inicialmente deja entrar al proceso primigenio (*turno=0).

Disponemos de las siguientes funciones para controlar la exclusin mutua:
pHijoQuiere(): comprueba si algun proceso quiere acceder a su seccion critica:
recorre "entrarSC[]" si alguna componente es "T", en cuyo caso devuelve "T", de otro modo "F".
elSiguiente(): busca el proceso que tiene intencion de entrar en su SC, en la lista
"entrarSC[]", a partir del proceso actual. Si no encuentra ninguno se toma el anterior.

Tambin tenemos una funcin que vara el contenido de la variable compartida recurso.
Esta funcin es incrementa().

Programa:

#include <stdio.h>
#include <sys/wait.h>
#include "rshmem.h"
/* constantes logicas */
#define F 0
#define T 1
/* Numero de procesos en total */
#define N 4
/* Numero de iteraciones para la tarea de cada proceso */
#define NITER 500

* definicion de funciones */
*void incrementa()
*incrementa el valor del contenido del recurso compartido en tantas
*unidades como se indique en la variable k.
void incrementa(int *mem, int k){
int i;
i=*mem;
TP i=i+k;
TP *mem=i;
}
* pHijoQuiere()
* comprueba si algun proceso quiere acceder a su seccion critica:
* recorre "intencion[]" (menos "proc") si alguna componente es "T", en cuyo
* caso devuelve "T", de otro modo "F".

int pHijoQuiere (int intencion[], int proc, int NProc){
int i;
for (i=1; i<NProc; i++)
if (intencion[(proc+i)%NProc]==T ) return T;
return F; /* ninguno tiene intencion de entrar */
}


* elSiguiente()
* busca el proceso que tiene intencion de entrar en su SC, en la lista
* "intencion[]", a partir del proceso "proc". Si no encuentra ninguno
* se toma (proc+NProc-1)%NProc (el anterior mod NProc).

int elSiguiente (int intencion[], int proc, int NProc){
int j;
for (j=1; j<NProc-1; j++)
if (intencion[(proc+j)%NProc] == T) return (proc+j)%NProc ;
return (proc+NProc-1)%NProc ;
}
int main(){
int i; /* variable auxiliar contador*/
int *recurso; /* recurso compartido*/
int idProc ; /* identificador de proceso para uno mismo */
int *entrarSC; /* entrarSC[idProc]=T : idProc quiere entrar en s.c.
entrarSC[idProc]=F : idProc no quiere */
int *turno; /* turno de cada proceso (idProc) */
/*crea zona de memoria compartida*/
if (!crearMemoria()) {
fprintf(stderr, "error de crearMemoria\n");
exit(-1) ;
}
/* asignacion de memoria a los punteros*/
recurso = (int *) memoria; memoria += sizeof(int);
turno = (int *) memoria; memoria += sizeof(int);
entrarSC = (int *) memoria; memoria += sizeof(int)*N;
/* inicializacion de variables en memoria compartida */
*recurso = 0;
/* ningun proceso quiere entrar en su seccion critica todavia */
for (i=0; i<N-1; i++)
entrarSC[i]=F;
*turno=0; /* el turno es del padre */
/* creacion de procesos */
idProc = 0; /* para el proceso primigenio */
while (idProc<N-1) {
if (fork()) { /**** proceso padre */
/* tarea de cada proceso */
for (i=0; i<NITER; i++){
/********seccion entrada********/
if ( pHijoQuiere(entrarSC, idProc, N)== F )
*turno=idProc;
entrarSC[idProc]=T;
while(pHijoQuiere(entrarSC, idProc, N)){
if(*turno != idProc){ /* si no es su turno */
entrarSC[idProc]=F;
while(*turno != idProc); /* mientras no sea su turno */
entrarSC[idProc]=T;
}
}
/********fin seccion entrada*******
*/
incrementa(recurso,-10); /********seccion critica********/
/********seccion salida*******
*/
*turno = elSiguiente(entrarSC, idProc, N);
entrarSC[idProc]=F;
/*
*******fin seccion salida********/
} /* fin for (tarea) */
(void) wait(NULL) ;
printf("Elrecurso valia 0 y ahora vale %d\n", *recurso);
if (idProc == 0) /* el proceso primigenio debe borrar la memoria */
if (!eliminarMemoria())
fprintf(stderr, "error de eliminarMemoria\n");
exit(0);
} else { /**** proceso hijo */
idProc++;
}
}/*idProc=N-1*/
/*Tarea del proceso nieto de todos los procesos*/
for (i=0; i<NITER; i++){
/********seccion entrada*******
*/
entrarSC[idProc]=T;
while(pHijoQuiere(entrarSC, idProc, N)){
if(*turno != idProc){ /* si no es su turno */
entrarSC[idProc]=F;
while(*turno != idProc); /* mientras no sea su turno */
entrarSC[idProc]=T;
}
}
/*
*******fin seccion entrada********/
incrementa(recurso,-10); /********seccion critica********/
/********seccion salida*******
*/
*turno = elSiguiente(entrarSC, idProc, N);
entrarSC[idProc]=F;
/*
*******fin seccion salida********/
} /* fin for (tarea) */
exit(0);
}/*main*/


Bibiliografia:
http://www.infor.uva.es/~cllamas/concurr/pract98/sisos13/
http://bourneshell.wordpress.com/2012/10/26/algoritmos-de-dekker/
http://www.buenastareas.com/ensayos/Algoritmo-De-Dekker-Peterson/871136.html

Das könnte Ihnen auch gefallen