Documentos de Académico
Documentos de Profesional
Documentos de Cultura
ALGORITMO DE PETERSON
Veamos un pequeño ejemplo, tener tres pizarras afuera del baño es decir una
bandera para cada uno de ellos y una tercera pizarra que va a ser la del desempate
que va a ser tú por lo tanto estas variables que van a ser compartidas pues va a ser
el arreglo de dos banderas cuyos valores iníciales los vamos a establecer con falso
y la variable turno que puede tener el valor inicial de cero y de uno pero para este
ejemplo le vamos a establecer el valor de cero ahora cuando un proceso quiere
entrar a la sección crítica lo que va a hacer es que va a poner su bandera en
verdadero y va a poner la variable turno con el número del otro proceso es decir
podríamos decir que van a ser muy educados porque lo que están diciendo es yo
quiero entrar pero en el caso de que tú también quieres entrar tú vas a tener tu turno,
entonces va a tener el valor de 0 o de 1 antes de entrar a la sección crítica.
Ahora comprueban si la bandera del otro proceso es verdadera y además es su
turno entonces me tengo que esperar en este ciclo while de acuerdo cuando
finalmente salgo de éste while puedo entrar a la sección crítica.
Pseudocódigo
bandera[0] = 0
bandera[1] = 0
turno =0
p0: bandera[0] = 1 p1: bandera[1] = 1
turno = 1 turno = 0
while( bandera[1] && turno == 1 ); while( bandera[0] && turno == 0 );
//no hace nada; espera. //no hace nada; espera.
// sección crítica // sección crítica
Código en C++:
#include <cstdlib>
#include <iostream>
#include <thread>
#include <time.h>
#include <curses.h>
#include <stdio.h>
#include <string.h>
bool proceso1_desea_entrar;
bool proceso2_desea_entrar;
int proceso_favorecido;
bool cancelar;
WINDOW * winA;
WINDOW * winB;
WINDOW * winTop;
WINDOW * winBottom;
void retardo_aleatoreo()
{
srand(time(NULL));
retardar_unos_milisegundos(tiempo);
}
void ejecutar_seccion_critica_1() {
waddstr(winA, "#");
wrefresh(winA);
retardar_unos_milisegundos(15000);
}
void proceso1() {
while (!cancelar) {
proceso1_desea_entrar = true;
proceso_favorecido = 2;
if (cancelar) break;
ejecutar_seccion_critica_1();
proceso1_desea_entrar = false;
}
void ejecutar_seccion_critica_2() {
waddstr(winB, "@");
wrefresh(winB);
retardar_unos_milisegundos(15000);
}
void proceso2() {
while (!cancelar) {
proceso2_desea_entrar = true;
proceso_favorecido = 1;
if (cancelar) break;
ejecutar_seccion_critica_2();
proceso2_desea_entrar = false;
}
void inicializar_pantallas() {
setlocale(LC_ALL, "spanish");
initscr();
erase();
refresh();
cbreak();
noecho();
keypad(stdscr, TRUE);
int h, w;
getmaxyx(stdscr, h, w);
wmove(winTop, 0, (w / 2) - strlen(titulo));
waddstr(winTop, titulo);
wrefresh(winTop);
void esperar_enter_del_usuario() {
waddstr(winBottom, "Presione la tecla [Enter] para salir.");
wrefresh(winBottom);
getch();
refresh();
}
inicializar_pantallas();
cancelar = false;
proceso1_desea_entrar = false;
proceso2_desea_entrar = false;
proceso_favorecido = 1;
thread p1(proceso1);
thread p2(proceso2);
esperar_enter_del_usuario();
cancelar = true;
p1.join();
p2.join();
endwin();
return EXIT_SUCCESS;
}
Programa en Ejecución:
Al iniciar el proceso indica que desea entrar a su sección crítica, pero a la vez
favorece al otro proceso.
Se crea un ciclo de espera hasta que otro proceso haya salido de su sección crítica
y que el proceso favorecido sea el proceso actual.
Se ejecuta la sección crítica.
Se indica que el proceso ya salió de la sección crítica
(procesoX_desea_entrar=false).
Se incluye una variable cancelar que se establece a true cuando el usuario presiona
la tecla Enter para poder finalizar los procesos en cualquier momento.
SECCIÓN CRÍTICA
Ninguno de los procesos que estén en ejecución fuera de su sección critica puede
bloquear a otros procesos.
Ningún proceso debe esperar demasiado tiempo para entrar en su sección critica.
Una solución al problema de la sección crítica debe cumplir los tres requisitos
siguientes:
3. Espera limitada: debe haber un límite en el número de veces que se permite que
los demás procesos entren en su sección crítica después de que un proceso haya
efectuado una solicitud para entrar en la suya y antes de que se con cada esa
solicitud.
EN QUE CONSISTE EL ALGORITMO DE PETERSON Y GENERALIZACIÓN
PARA N PROCESOS:
/**************************************************************************************
**************************************************************************************/
#include <stdlib.h>
#include "rshmem.h"
#define Nproc 3
int i;
i=*mem;TP
i=i+k;TP
*mem=i;
i, /* variable contador */
j, /* variable contador */
l; /* variable contador */
if(argn!=3){
exit(1);
if(!crearMemoria()){
fprintf(stderr,"Error de crearMemoria()\n");
nIteraciones=atoi(argv[1]);
recurso=(int*)memoria;
turno=(int*)recurso+sizeof(int);
marcaFin[0]=(char*)turno+sizeof(int);
for(i=1;i<Nproc;i++)
marcaFin[i]=(char*)marcaFin[i-1]+sizeof(int);
c[0]=(char*)marcaFin[Nproc-1]+sizeof(int);
for(i=1;i<Nproc;i++)
c[i]=(char*)c[i-1]+sizeof(int);
*recurso=0;
for(i=0;i<Nproc;i++)
*(marcaFin[i])='p';
for(i=0;i<Nproc;i++)
*(c[i])='F';
for(i=0;i<Nproc;i++){
if(fork()==0){
if((fsal=fopen(argv[2],"a+"))==NULL){
exit(-1);
for(j=0;j<nIteraciones;j++){
/* seccion de entrada */
do{
*(c[i])='T';
k=*turno;
while(k!=i){
if(*(c[k])!='F')
k=*turno;
else
k=(k+1)%Nproc;
*(c[i])=ENSECR;
k=0;
while((k<Nproc)&&((k==i)||((*(c[k]))!=ENSECR)))
k=k+1;
}while(!((k>=Nproc)&&((*turno==i)||(*(c[*turno])=='F'))));
*turno=i;
/* seccion critica */
incrementa(recurso,5);
fflush(fsal);
/* seccion de salida */
k=(*turno+1)%Nproc;
while(*(c[k])=='F')
k=(k+1)%Nproc;
*turno=k;
*c[i]='F';
fclose(fsal);
*(marcaFin[i])='x';
exit(0);
for(l=0;l<Nproc;l++)
while(*(marcaFin[l])!='x');
if((fsal=fopen(argv[2],"a+"))==NULL){
exit(-1);
fflush(fsal);
fclose(fsal);
if(!eliminarMemoria())
fprintf(stderr,"Error de eliminarMemoria\n");
exit(0);