-
Notifications
You must be signed in to change notification settings - Fork 0
/
Proceso.java
227 lines (175 loc) · 8.01 KB
/
Proceso.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.rmi.Naming;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
public class Proceso {
static int id, n, delay;
static List<Integer> RN = new ArrayList<>();
static Boolean bearer;
static int sequenceNumber = 0;
static Log myLog = null;
public static void main(String[] args){
Token t = null;
String color = "Verde";
//Se parsean los elementos de entrada
id = Integer.parseInt(args[0]);
n = Integer.parseInt(args[1]);
delay = Integer.parseInt(args[2]);
if (args[3].equals("true")){
bearer = true;
}
else{
bearer = false;
}
//Se inicializa la lista RN
for(int i=0; i<n; i++){
RN.add(0);
}
//Se inicializa el log
try {
myLog = new Log("./logs/logP"+id);
}catch (Exception e){
e.printStackTrace();
}
myLog.logger.info("Estado Inicial: id: "+id+", n: "+n+", delay: "+delay+", bearer: "+bearer);
myLog.logger.info("[Proceso "+id+"] Color del semaforo: "+color);
myLog.logger.setLevel(Level.INFO);
try{
//Se procede a pedir el token desde el RMI
app aplicacion = (app) Naming.lookup("//localhost:" + 8080 + "/app");
//Se procede a generar el thread que escucha las peticiones multicast
Thread threadIn = new Thread(new inChannel());
threadIn.start();
//Se procede a dar tiempo a los procesos para que todos esten Online
Thread.sleep(1000*10);
/*Desde aquí en adelante comienza el intento de entrar en la zona crítica*/
Thread.sleep(delay);
//Caso en el que tengo el token, entonces debo de mandar la petición e iniciar
if (bearer){
t = new Token(n);
aplicacion.request(id, ++sequenceNumber);
}
//Caso en el que no parto con el token
if (!bearer){
aplicacion.request(id, ++sequenceNumber);
color = "Amarillo";
myLog.logger.info("[Proceso "+id+"] Color del semaforo: "+color);
myLog.logger.info("[Proceso "+id+"] Se espera el token");
t = aplicacion.waitToken(id);
myLog.logger.info("[Proceso "+id+"] Token recibido");
}
//Le doy 1 segundo para que sincronize mensajes que vengan en curso antes de entrar a la zona crítica
Thread.sleep(1000*1);
color = "Rojo";
myLog.logger.info("[Proceso "+id+"] Color del semaforo: "+color);
myLog.logger.info("[Proceso "+id+"] Entrando en la zona crítica.");
/*Se comienzan a realizar cosas de la zona crítica*/
myLog.logger.info("[Proceso "+id+"] Saliendo de la zona crítica.");
color = "Verde";
myLog.logger.info("[Proceso "+id+"] Color del semaforo: "+color);
/*Empieza el proceso de modificar LN, la cola y ver a quién le voy a mandar el token*/
//Después de que termina la zona crítica, hay que actualizar que se le realizó la petición al proceso que tenía el token
//t.LN.set(id, RN.get(id));
t.LN.set(id, sequenceNumber);
//Ahora hay que recorrer LN y RN para así encolar a los procesos con peticiones pendientes que aun no son considerados
for(int i=0; i<t.LN.size() ; i++){
//Caso en que puede haber una petición pendiente
if (RN.get(i) == t.LN.get(i) + 1){
//solo si no esta en la cola hay que añadirlo
if (!t.Queue.contains(i)){
t.Queue.add(i);
}
}
}
//Finalmente ahora debo de ver quién esta en el frente de la cola, para así enviarle el token
int siguiente;
myLog.logger.info("[Proceso "+id+"] Estado RN: "+RN+" "+t);
//Antes de verificar cómo esta la cola, voy a ver si ya terminó el algoritmo, es decir todos pasaron
//1 vez satisfactoriamente por la ruta crítica
Boolean termino = true;
for(int i=0; i<t.LN.size(); i++){
if (t.LN.get(i) == 0){
termino=false;
}
}
//En caso de que yo soy el último proceso debo de terminar el algoritmo
if (termino){
myLog.logger.info("[Proceso "+id+"] Fin de la ejecución del algoritmo.");
aplicacion.kill();
}
//Si es que no soy el último debo pasar el token al siguiente que lo requiera
else{
//Si es que no hay nadie en la cola voy a retener el token, verificaré cada 1 segundo para mandarlo
while (t.Queue.size() == 0){
Thread.sleep(1000*1);
//Voy a ver las solicitudes en curso
for(int i=0; i<t.LN.size() ; i++){
//Caso en que puede haber una petición pendiente
if (RN.get(i) == t.LN.get(i) + 1){
//solo si no esta en la cola hay que añadirlo
if (!t.Queue.contains(i)){
t.Queue.add(i);
}
}
}
}
siguiente = t.Queue.get(0);
myLog.logger.info("[Proceso "+id+"] Le enviaré el token a: "+siguiente);
aplicacion.takeToken(t);
t = null;
}
//Como se va a salir mato el thread que esta esuchando en el multiccast y después salgo con exit
threadIn.stop();
myLog.logger.info("[Proceso "+id+"] Fin de la ejecución.");
System.exit(0);
}catch (Exception e){
e.printStackTrace();
}
}
public static class inChannel implements Runnable{
@Override
public void run() {
try {
MulticastSocket mcSocketIn;
InetAddress ipMulti;
int puertoMulti;
//Se inicializa la ip y puertos multicast
ipMulti = InetAddress.getByName("230.0.0.1");
puertoMulti = 4545;
//Se inicializa el socket multi cast para recibir mensajes
mcSocketIn = new MulticastSocket(4545);
mcSocketIn.joinGroup(ipMulti);
//Se crea un buffer
byte[] buf = new byte[256];
while(true){
//Se crea un paquete el cual leera el contenido del multicast
DatagramPacket paqueteIn = new DatagramPacket(buf, buf.length);
mcSocketIn.receive(paqueteIn);
/*SE PROCEDE A ESPERAR HASTA QUE LLEGUE ALGÚN MENSAJE*/
//Se empieza a procesar el mensaje
String received = new String(paqueteIn.getData(), paqueteIn.getOffset(), paqueteIn.getLength());
//Procesamiento de peticiones según susuki kasami
//Solo se acepta si seq > RN[id]
String[] info = received.split("-");
if (info[0].equals("request")){
int idIn = Integer.parseInt(info[1]);
int seq = Integer.parseInt(info[2]);
if (seq > RN.get(idIn)){
RN.set(idIn, seq);
myLog.logger.info("[Proceso "+id+"] Petición aceptada, RN:"+RN);
}
else{
myLog.logger.info("[Proceso "+id+"] Petición rechazada.");
}
}
}
} catch (IOException e){
e.printStackTrace();
}
}
}
}