domingo, 6 de septiembre de 2015

Mensajes y semaforos

Ejercicio1
public class MaxminDemo {
    public static final int numProcesos=5;


    public static void main(String[] args) {
        ArrayList<Channel<Integer>> izq=new ArrayList<Channel<Integer>>();
        ArrayList<Channel<Integer>> der=new ArrayList<Channel<Integer>>();

        for (int i = 0; i < numProcesos+1; i++) {
            izq.add(new Channel<Integer>());
            der.add(new Channel<Integer>());
        }
       
        Nodo []p=new Nodo[numProcesos];
        for (int i = 0; i < numProcesos; i++) {
            p[i]=new Nodo(i,der.get(i),izq.get(i+1),izq.get(i),der.get(i+1));
            p[i].start();
        }
   
    }
}
class Nodo extends Thread {
    int id;
    Channel<Integer> entradaIzq, entradaDer, salidaIzq, salidaDer;

    public Nodo(int id, Channel<Integer> enti, Channel<Integer> entd, Channel<Integer> sali, Channel<Integer> sald) {
        this.id = id;
        this.entradaIzq = enti;
        this.entradaDer = entd;
        this.salidaIzq = sali;
        this.salidaDer = sald;
    }

    public void run() {
        Random r = new Random();
        int num, min, max;

        num = r.nextInt(1000);
        min = max = num;
        System.out.println("se inicializa el nodo con: "+ min+"-"+max);
        try {
            //si no es el primero recibe de la izquierda el valor minimo y maximo
            if (id != 0) {
                min = entradaIzq.receive().intValue(); // recibe el minimo actual desde la izquierda
                max = entradaIzq.receive().intValue(); // recibe el maximo actual desde la izquierda
                System.out.println(min+"-"+max);
            }
            // actualiza min y max
            if (num < min) {
                min = num;
            }
            if (num > max) {
                max = num;
            }

            //siempre que no sea el ultimo envia a la derecha el minimo y el maximo
            if (id != MaxminDemo.numProcesos - 1) { // enviar hacia la derecha
                salidaDer.send(new Integer(min));
                salidaDer.send(new Integer(max));

                // esperar min y max definitivos
                min = entradaDer.receive().intValue();
                max = entradaDer.receive().intValue();
            }
            System.out.println("nodo " + id + " minimo: " + min + " maximo: "
                    + max);

            if (id != 0) { // enviar hacia la izquierda
                salidaIzq.send(new Integer(min));
                salidaIzq.send(new Integer(max));
            }
        } catch (InterruptedException ex) {
        }
    }
}
- - - -
public class HebrasIguales {

    public static int numProcesos = 5;
   
    public static void main(String[] args) {
        ArrayList<Channel<Integer>> izq = new ArrayList<Channel<Integer>>();
        ArrayList<Channel<Integer>> der = new ArrayList<Channel<Integer>>();
       
        for (int i =0 ;i<numProcesos+1;i++){
            izq.add(new Channel<Integer>());
            der.add(new Channel<Integer>());
        }
       
        Nodo_2 [] p = new Nodo_2[numProcesos];
       
        for (int i =0 ;i<numProcesos;i++){
            p[i] = new Nodo_2(i, der.get(i),der.get(i+1),izq.get(i),izq.get(i+1));
            p[i].start();
           
        }    
    }
}
 public class Nodo_2 extends Thread {

    int num, id, izq, der;
    int cont = 0;
    Channel<Integer> entradaI, entradaD, salidaD, salidaI;
    String fin = "";
    ArrayList<Integer> numeros = new ArrayList<Integer>();


    public Nodo_2(int id, Channel<Integer> entradaD, Channel<Integer> salidaD,
            Channel<Integer> salidaI, Channel<Integer> entradaI) {
        this.id = id;
        this.entradaD = entradaD;
        this.entradaI = entradaI;
        this.salidaD = salidaD;
        this.salidaI = salidaI;
    }

    public void run() {

        Random rnd = new Random();
        num = rnd.nextInt(10) + 1;

        try {
            if (id != 0) {
                izq = entradaD.receive().intValue();
            }

            if (id != HebrasIguales.numProcesos - 1) {
                salidaD.send(num);
            }
            if (id != 0) {
                salidaI.send(num);
            }
            if (id != HebrasIguales.numProcesos - 1) {
                der = entradaI.receive().intValue();
            }
            numeros.add(num);

            //System.out.println("[" + izq + "-" + num + "-" + der + "]");
        } catch (InterruptedException e) {

        }
      
        for (int i = 0; i < numeros.size(); ++i) {
            System.out.print("["+numeros.get(i)+",p:"+id+"]");
        }
      
    }

}
- - - -

public class hebranum {
    private static final int NHEBRAS = 10;
    static class BidirChannel<T> {
        private Channel<T> canal1 = new Channel<T>();
        private Channel<T> canal2 = new Channel<T>();
        private int mode = 0;
        public class EndPoint {
            private Channel<T> canal_s;
            private Channel<T> canal_r;
            private EndPoint(int mode) {
                switch (mode) {
                case 0:
                    canal_s = canal1;
                    canal_r = canal2;
                    break;
                case 1:
                    canal_s = canal2;
                    canal_r = canal1;
                    break;
                default:
                    throw new IllegalArgumentException();
                }
            }
            public void send(T v) throws InterruptedException {
                canal_s.send(v);
            }
            public T receive() throws InterruptedException {
                return canal_r.receive();
            }
            public void addToSelect(Select sel) {
                sel.add(canal_r);
            }
            public void guard(boolean g) {
                canal_r.guard(g);
            }
            public Channel<T> sendChannel() {
                return canal_s;
            }
            public Channel<T> recvChannel() {
                return canal_r;
            }
        }
        public EndPoint getEndPoint() {
            return new EndPoint(mode++);
        }
        public EndPoint getEndPoint(int mode) {
            return new EndPoint(mode);
        }
    }
    static class Hebra implements Runnable {
        private Random rnd = new Random();
        private int nhebras;
        private int id;
        private BidirChannel<Integer>.EndPoint izq;
        private BidirChannel<Integer>.EndPoint dch;
        public Hebra(int nhebras, int id,
                     BidirChannel<Integer>.EndPoint i,
                     BidirChannel<Integer>.EndPoint d) {
            this.nhebras = nhebras;
            this.id = id;
            this.izq = i;
            this.dch = d;
        }
        public void run () {
            ArrayList<Integer> hebras_ids = new ArrayList<Integer>();
            int num, h, n;
            num = rnd.nextInt(10);
            synchronized (System.out) {
                System.out.println("INICIO Id: "+id+" Num: "+num);
            }
            try {
                if (izq != null) {
                    for (int i = 0; i < id; ++i) {
                        h = izq.receive();
                        n = izq.receive();
                        if (dch != null) {
                            dch.send(h);
                            dch.send(n);
                        }
                        if (n == num) {
                            hebras_ids.add(h);
                        }
                    }
                }
                if (dch != null) {
                    dch.send(id);
                    dch.send(num);
                }
                if (dch != null) {
                    for (int i = 0; i < (nhebras-id-1); ++i) {
                        h = dch.receive();
                        n = dch.receive();
                        if (izq != null) {
                            izq.send(h);
                            izq.send(n);
                        }
                        if (n == num) {
                            hebras_ids.add(h);
                        }
                    }
                }
                if (izq != null) {
                    izq.send(id);
                    izq.send(num);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            synchronized (System.out) {
                System.out.print("Id: "+id+" Num: "+num+" [");
                for (int i = 0; i < hebras_ids.size(); ++i) {
                    System.out.print(" "+hebras_ids.get(i));
                }
                System.out.println(" ]");
            }
        }
    }

    public static void main(String[] args) {
        // H0 <--0--> H1 <--1--> H2 <--2--> H3 ... Hn-1
        try {
            ArrayList<BidirChannel<Integer>> canal=new ArrayList<BidirChannel<Integer>>();
            for (int i = 0; i < NHEBRAS-1; ++i) {
                canal.add(new BidirChannel<Integer>());
            }
            Thread[] hebra = new Thread[NHEBRAS];
            for (int i = 0; i < hebra.length; ++i) {
                BidirChannel<Integer>.EndPoint izq = null;
                BidirChannel<Integer>.EndPoint dch = null;
                if (i-1 >= 0) { izq = canal.get(i-1).getEndPoint(0); }
                if (i < canal.size()) { dch = canal.get(i).getEndPoint(1); }
                hebra[i] = new Thread(new Hebra(NHEBRAS, i, izq, dch));
                hebra[i].start();
            }
            for (int i = 0; i < hebra.length; ++i) {
                hebra[i].join();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
- - - -
Ejercicio 4(Camellos)
enum Estado { gana, pierde, sigue};

public class CamelloDemo {
    static final int NUMC=10;
   
    /**
     * @param args
     */
    public static void main(String[] args) {
        ArrayList<Channel<Integer>> c=new ArrayList<Channel<Integer>>();
        ArrayList<Channel<Estado>> gana=new ArrayList<Channel<Estado>>();


        for (int i = 0; i < NUMC; i++) {
            c.add(new Channel<Integer>());
            gana.add(new Channel<Estado>());
        }
       
        Camello []cam=new Camello[NUMC];
        for (int i = 0; i < NUMC; i++) {
            cam[i]=new Camello(i,c.get(i),gana.get(i));
            cam[i].setName("cam"+i);
        }
       
        Caseta cas=new Caseta(c,gana);
        cas.setName("cas");
       
        for (int i = 0; i < NUMC; i++) {
            cam[i].start();
        }
       
        cas.start();
    }

}



class Camello extends Thread {
    Channel<Integer> sal;
    Channel<Estado> gana;
    int id;
   
    Camello(int id,Channel<Integer> sal,Channel<Estado> gana) {
        this.id=id;
        this.sal=sal;
        this.gana=gana;
    }
   
   
    public void run() {
        Random r=new Random();
        int v;
        Estado est;
        boolean fin=false;
       
        try {
        do {
            v=r.nextInt(3);
            sal.send(new Integer(v));
            est=gana.receive();
            fin=est==Estado.pierde || est==Estado.gana;
            if (est==Estado.gana) {
           
                System.out.println("Camello "+id+" soy el ganador");           
            }
            else if (est==Estado.pierde) {
                System.out.println("Camello "+id+" pierdo");
            }
        } while (!fin);
        } catch (InterruptedException ex) {}
    }
}



class Caseta extends Thread {
    ArrayList<Channel<Integer>> c;
    ArrayList<Channel<Estado>> gana;
    Select sel;
   
    Caseta(ArrayList<Channel<Integer>> c,ArrayList<Channel<Estado>> gana) {
        this.c=c;
        this.gana=gana;
        sel=new Select();
        for (int i=0;i<c.size();i++) {
            sel.add(c.get(i));
        }       
    }
   
   
    public void run() {
        boolean terminado=false;
        int []posiciones=new int[CamelloDemo.NUMC];
        int rama=0,ju;
        Estado res;

        for (int i=0;i<posiciones.length;i++)
            posiciones[i]=0;

        try {
        do {           
            rama=sel.choose();
            ju=c.get(rama-1).receive().intValue();
            System.out.println("camello "+(rama-1)+" avanza "+ju+" queda: "+(10-posiciones[rama-1]-ju));
            posiciones[rama-1]=posiciones[rama-1]+ju;

            terminado=posiciones[rama-1]>=10;
            if (terminado)
                res=Estado.gana;
            else
                res=Estado.sigue;
            gana.get(rama-1).send(res);       
           
        } while (!terminado);

        // Informar al resto de la derrota
        for (int i=0;i<CamelloDemo.NUMC-1;i++) {
            // Acepto sus jugadas
            rama=sel.choose();
            c.get(rama-1).receive();
           
            // Informo de derrota
            res=Estado.pierde;
            gana.get(rama-1).send(res);   
        }

        } catch (InterruptedException ex) {}

    }

}

- - - -
Semaforos

public class Robots {
    static int tamCinta = 10;
    static int numEmpaq = 0;
    static int[] cinta = new int[tamCinta];
    static Semaphore semHayDatos = new Semaphore(tamCinta);
    static Semaphore[] semProd = {new Semaphore(0), new Semaphore(0), new Semaphore(0)};
    static Semaphore mutexNumEmpaq = new Semaphore(1);
//    static Semaphore mutexCinta = new Semaphore(1);
   
   
    static class Productor extends Thread {
        public void run() {
            int tipo,i;
            char producto;
            Random r=new Random();
           
            try {
                while (true) {
                    tipo=r.nextInt(3);
                    System.out.printf("Produciendo tipo %d\n", tipo);
                    //Thread.sleep((int) (Math.random() * 3000));
                    semHayDatos.acquire();
                    i=0;
                    //mutexCinta.acquire();
                    while (cinta[i] != -1) i++;
                    cinta[i] = tipo;
                    //mutexCinta.release();

                    semProd[tipo].release();
                }
            } catch (InterruptedException e) {}
        }
    }
   
    static class Empaquetador extends Thread {
        private int tipo;
       
        Empaquetador(int tipo) {
            this.tipo = tipo;
        }
       
        public void run() {
            int i;
            try {
                while (true) {
                    semProd[tipo].acquire();
                    i=0;
                    //mutexCinta.acquire();

                    while (cinta[i] != tipo) i++;
                                       
                    System.out.printf("Empaquetando tipo %d en pos %d\n", tipo, i);                   
                    cinta[i] = -1;
                    //mutexCinta.release();

                    semHayDatos.release();
                   
                    //Thread.sleep((int) (Math.random() * 3000));
                    mutexNumEmpaq.acquire();
                    numEmpaq++;
                    System.out.printf("%d empaquetados.\n", numEmpaq);
                    mutexNumEmpaq.release();
                }
            } catch (InterruptedException e) {}
        }
    }
   
    public static void main(String[] args) {
        Productor prod = new Productor();
        Empaquetador[] empaqs = {new Empaquetador(0), new Empaquetador(1), new Empaquetador(2)};
        for (int i=0;i<tamCinta;i++)
            cinta[i]=-1;
        prod.start();
        for (Empaquetador e : empaqs)
            e.start();
    }
}

- - - -
public class Grupo {
// suponemos la sala vacia
private Semaphore semProcesoA = new Semaphore(1, true);
private Semaphore semProcesoB = new Semaphore(1, true);
private Semaphore mutex = new Semaphore(1, true);
private boolean completoGrupoA = false, completoGrupoB = false;
private int idA, idB;
public void nuevoGrupoA(int id) throws InterruptedException {
//se obtiene un permiso para A y se bloquea
semProcesoA.acquire();
mutex.acquire();
System.out.println("proceso A = [" + id + "] llega");
idA = id;
completoGrupoA = true;
this.formarGrupo();
mutex.release();
}
public void nuevoGrupoB(int id) throws InterruptedException {
semProcesoB.acquire();
mutex.acquire();
System.out.println("proceso B = [" + id + "] llega");
idB = id;
completoGrupoB = true;
this.formarGrupo();
mutex.release();
}
//verifica que los dos esten en la sala y crea
public void formarGrupo() throws InterruptedException {
if (completoGrupoA && completoGrupoB) {
//libera la sala permitiendo el acceso a A y B
semProcesoA.release();
semProcesoB.release();
completoGrupoA = false;
completoGrupoB = false;
System.out.println("Se crea el grupo con [A =" + idA + "
y B= " + idB + "]"+"\n");
//espera un tiempo antes de pedir crear otro grupo
new Thread().sleep(2000);
}
}
}

No hay comentarios:

Publicar un comentario