Bressam icon

AlgoritmoRicartAgrawala

Bressam | PRO | 06/28/18 07:12:08 AM UTC | 0 ⭐ | 286 👁️ | Never ⏰ | []
Java |

13.02 KB

|

None

|

0 👍

/

0 👎

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package algoritmoricartagrawala;
 
import java.io.IOException;
import static java.lang.Math.random;
import static java.lang.StrictMath.random;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
 
/**
 *
 * @author giovanne.gaspareto
 */
public class AlgoritmoRicartAgrawala {
    static InetAddress              grupo;
    static MulticastSocket          s;
    static DatagramPacket           msg;
    static DatagramPacket           recv;
    private static Scanner          keyboard;
    
    
    static boolean                  executarProcesso = true;
    static boolean                  aguardaPermissaoRegiaoCritica = false;
    static boolean                  regiaoCritica = false;
    
    static final String         GROUP_IP = "224.0.0.1";
    static final int            MULTICAST_PORT = 2000;
    static int                  IDProcesso = 0;
    static String               mensagem = "";
    static int                  numeroProcessosGrupo = 0;
    static int                  tempoRandom = 0;
    static int                  idProcessoNaRegiaoCritica = 0;
    static int                  idRecebido = 0;
    static int                  proximo =   0;
    
    
    
    static final String         OK_STRING = "ok";
    static final String         DESCONECTAR_STRING = "q";
    static final String         DIVISOR_STRING = ";";
    static final String         GRUPO_COMPLETO_STRING = "gc";
    static final String         EXISTE_PROCESSO_REGIAO_CRITICA = "regiao critica";
    static final String         REQUISICAO_REG_CRITICA_STRING  =   "rc";
    static final String         SAINDO_REGIAO_CRITICA_STRING  = "sc";
    static final String         ENTROU_REGIAO_CRITICA_STRING = "ec";
    
    static final int            NOVO_MEMBRO = 1;
    static final int            GRUPO_COMPLETO = 2;
    static final int            REQUISICAO_REG_CRITICA = 3;
    static final int            SAINDO_REGIAO_CRITICA = 4;
    static final int            ENTROU_REGIAO_CRITICA = 5;
    
    
    static List<Integer> listaEsperaRegiaoCritica = new ArrayList<Integer>();  //lista com IDs dos processos aguardando pela regiao critica
    
    
    public static String receiveMessageGroup(){
        byte[] buf=new byte[1000];
        recv=new DatagramPacket(buf, buf.length);
        try {
            s.setSoTimeout(10);
            s.setLoopbackMode(false);
           // System.out.println("timeout no recevei sem nada: " + s.getSoTimeout());
            s.receive(recv);
            byte[] dest=new byte[recv.getLength()];
            System.arraycopy(recv.getData(), 0, dest, 0, dest.length);
            String mensagemRecebida = new String(recv.getData(),recv.getOffset(),recv.getLength());
         //   System.err.println("Mensagen recebida: "+ mensagemRecebida);
            return mensagemRecebida;
        } catch (SocketTimeoutException ex) {
          // Logger.getLogger(ProcessoSender.class.getName()).log(Level.SEVERE, null, ex);
            return "x;0;0";
    } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return "x;0;0";
        }
    }
    public static void sendMessageGroup(String msgStr) {
        msg=new DatagramPacket(msgStr.getBytes(), msgStr.length(),grupo, 2000);
       // System.out.println("Enviando mensagem para o grupo ...");
        try {
            s.send(msg);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    //Funcao de configuracao
    public static void setUp() {
        try {
            System.setProperty("java.net.preferIPv4Stack", "true"); // somente pra mac no wifi
            grupo=InetAddress.getByName(GROUP_IP);
            s=new MulticastSocket(MULTICAST_PORT);
            System.err.println("Entrando no grupo ...");
            s.joinGroup(grupo);
            System.err.println("Ok.");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
       
    }
    
    public static int geraRandomEntre(int min, int max){
        Random rn = new Random();
        return rn.nextInt(max-min+1)+min;
    }
    /**
     * @param args the command line arguments
     */
    
    public static int trataMensagem(String mensagemRecebida, DatagramPacket PacketLider){
        String[] partes = mensagemRecebida.split(DIVISOR_STRING);
        String operacao = partes[0];
        String mensagem = partes[1];
        idRecebido = Integer.parseInt(mensagem);
        
        if(operacao.equals(OK_STRING)){
            return  NOVO_MEMBRO;
        }
        else if(operacao.equals(GRUPO_COMPLETO_STRING)){
            return GRUPO_COMPLETO;
        }else if(operacao.equals(REQUISICAO_REG_CRITICA_STRING)){
            return REQUISICAO_REG_CRITICA;
        }else if(operacao.equals(SAINDO_REGIAO_CRITICA_STRING)){
            idProcessoNaRegiaoCritica = 0;
            return SAINDO_REGIAO_CRITICA;
        }else if(operacao.equals(ENTROU_REGIAO_CRITICA_STRING)){
            idProcessoNaRegiaoCritica = Integer.parseInt(mensagem);
            return ENTROU_REGIAO_CRITICA;
        }
        return -1;
    }
    
    public static void defineIDProcesso(){
        keyboard = new Scanner(System.in);
        System.out.println("Informe o ID deste processo: ");
        IDProcesso = keyboard.nextInt();
    }
    
    public static void lerGrupoTrataMensagem(){
        switch(trataMensagem(receiveMessageGroup(),recv)){//só cria timer apos estar de fato atuando na regiao critica, so acontecera quando receber um ok que o processo anterior liberou ela
            //ler mensagens ate receber ok que a regiao critica esta livre
            case REQUISICAO_REG_CRITICA:
                //Recebeu uma requisicao de regiao critica, todos atualizam a lista de espera
                listaEsperaRegiaoCritica.add(idRecebido);
                proximo = listaEsperaRegiaoCritica.get(0);
                if(proximo == IDProcesso && idProcessoNaRegiaoCritica == 0){ //é o primeiro da fila e nao ha nenhum processo na regiao critica
                    
                    aguardaPermissaoRegiaoCritica = false;
                    regiaoCritica = true;
                }
                break;
 
            case SAINDO_REGIAO_CRITICA:
                //verificar se seu proprio ID é o proximo a entrar na regiao critica, se for, envia que entrou e inicia timer, senao salva o id de quem entrou
                proximo = listaEsperaRegiaoCritica.get(0);
                System.out.println("[Processo "+ IDProcesso + "] Proximo da lista: " + proximo);
                if(proximo == IDProcesso){
                     aguardaPermissaoRegiaoCritica = false; //este processo é o proximo da fila, sai do loop de espera espera
                    //sendMessageGroup(ENTROU_REGIAO_CRITICA_STRING + DIVISOR_STRING + IDProcesso); //avisa outros processos que esta entrando
                    regiaoCritica = true;
                }
                break;
 
            case ENTROU_REGIAO_CRITICA:
                //se idProcesso = idProcessoNaRegiaoCritica, significa que pode entrar. aguardaPermissaoRegiaoCritica = false, regiaoCritica = true
                // remove ID do processo que entrou da lista de espera
                listaEsperaRegiaoCritica.remove(0);
                break;  
        }
    }
    
   public static void lerGrupoRegiaoNaoCritica(){
                       switch(trataMensagem(receiveMessageGroup(),recv)){//só cria timer apos estar de fato atuando na regiao critica, so acontecera quando receber um ok que o processo anterior liberou ela
                    //ler mensagens ate receber ok que a regiao critica esta livre
                    case REQUISICAO_REG_CRITICA:
                        //Recebeu uma requisicao de regiao critica, todos atualizam a lista de espera
                        listaEsperaRegiaoCritica.add(idRecebido);
                        break;
 
                    case ENTROU_REGIAO_CRITICA:
                        //se idProcesso = idProcessoNaRegiaoCritica, significa que pode entrar. aguardaPermissaoRegiaoCritica = false, regiaoCritica = true
                        // remove ID do processo que entrou da lista de espera
                       // if(IDProcesso != idRecebido){ //somente se for outro processo lendo que alguem entrou. Se for o proprio processo, ele ja se removeu da lista ao avaliar que era o proximo
                           listaEsperaRegiaoCritica.remove(0);
 
                        break;  
                }
    }
   
   public static void aguardaMembrosDoGrupo(){
    while(numeroProcessosGrupo<3){
            switch(trataMensagem(receiveMessageGroup(),recv)){
                case NOVO_MEMBRO:
                    numeroProcessosGrupo ++;
                    System.out.println("Novo processo Conectado ao Grupo!");
                    break;
                
                case GRUPO_COMPLETO:
                    numeroProcessosGrupo = 3;
                    break;
                default:
                  //  System.out.println("Case Default da espera grupo");
                    break;
            }
        }
        sendMessageGroup(GRUPO_COMPLETO_STRING+DIVISOR_STRING+IDProcesso);
   }
   
   public static void main(String[] args) {
        
        setUp();
        defineIDProcesso();
        sendMessageGroup(OK_STRING+DIVISOR_STRING+IDProcesso);
        
        aguardaMembrosDoGrupo();
        
        System.out.println("Grupo completo! Iniciar execucao.");
        
        tempoRandom = geraRandomEntre(2,16);
        //tempoRandom = 3;
        TimerProcessos timerAleatorio = new TimerProcessos(tempoRandom);
        System.out.println("[Processo " + IDProcesso + "] Entrando na regiao nao critica por " + tempoRandom + "s");
        while(executarProcesso){
            
            if(timerAleatorio.shouldCreate){
                
                //passou o tempo, entra ou sai da regiao critica
                if(aguardaPermissaoRegiaoCritica){//se estava na critica, agora nao esta mais
                    aguardaPermissaoRegiaoCritica = false;
                    tempoRandom = geraRandomEntre(2,16);
                }else{//se estava fora, agora fica na critica
                    aguardaPermissaoRegiaoCritica = true;
                }   
            }
            
            if(aguardaPermissaoRegiaoCritica){
                //fazer coisas da regiao critica
                System.out.println("[Processo " + IDProcesso + "] Aguardando entrada na regiao critica!");
                
                //Notifica a todos que deseja estar na regiao critica
                sendMessageGroup(REQUISICAO_REG_CRITICA_STRING + DIVISOR_STRING + IDProcesso);
 
                while(aguardaPermissaoRegiaoCritica){
                    lerGrupoTrataMensagem();
                }
                sendMessageGroup(ENTROU_REGIAO_CRITICA_STRING + DIVISOR_STRING + IDProcesso); //avisa outros processos que esta entrando na regiao critica
                //Iniciar timer da regiao critica
                timerAleatorio.cancelTimer();
                timerAleatorio = new TimerProcessos(tempoRandom);
                System.err.println("[Processo " + IDProcesso + "] Entrando na regiao critica! Tempo dentro da regiao: " + tempoRandom + "s");
                regiaoCritica = true;
                while(regiaoCritica){
                    //verifica timer, muda regiaoCritica para false apos fim do timer
                    if(timerAleatorio.shouldCreate){
                        regiaoCritica = false;
                        
                        //Inicia timer da regiao nao critica          
                        timerAleatorio.cancelTimer();
                        tempoRandom = geraRandomEntre(2,16);
                        timerAleatorio = new TimerProcessos(tempoRandom);
                    }
                    lerGrupoTrataMensagem();
                    //Ainda ler grupo, para atualizar lista de espera
                }
                System.err.println("[Processo " + IDProcesso + "]Fim da regiao critica!");
                sendMessageGroup(SAINDO_REGIAO_CRITICA_STRING + DIVISOR_STRING + IDProcesso); //notifica que saiu da regiao critica
                System.out.println("[Processo " + IDProcesso + "] Executando na regiao nao critica por " + tempoRandom + "s");
            }else{
                //fazer coisas da regiao nao critica
                //Ler grupo para atualizar controle de quem esta na regiao critica e atualizar a lista de espera
                lerGrupoRegiaoNaoCritica();
            }
            
        }
        System.exit(0);
    }
    
}

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎