pos eso, que no lo tengo claro, ya que osk me pone un ejemplito que no me termino de enterar...
no se cuando hay que poner el identificador, ni como se pone, ni pa que vale ni como matarlo...
un ejemplito mas o un enlace plis???
con signal matas un proceso, teniendo su id:
id_proceso_a_matar = procesoCualquiera();
signal(id_proceso_a_matar, S_KILL);
Pero debes prestar cuidado a que esa id sea válida, ya que si no existe se te cerrará el juego por error durante runtime.
Para evitar esto puedes usar la funcion exists() para comprobar antes que exista dicho proceso:
if (exists(id_proceso_a_matar))
signal(id_proceso_a_matar, S_KILL);
end
Además debes tener cuidado de no intentar acceder al proceso despues de muerto, asi que el exists() es de mucha ayuda con ello!
entonces, para crear ahora algun proceso hay que hacer:
[code language="bennu"]id_proceso_a_matar = procesoCualquiera();[/code]
¿no?
si, para matar un proceso en particular.
Si lo que quieres es matar a TODOS los procesos del mismo tipo se usa el TYPE:
signal(TYPE tuTipoDeProceso, S_KILL);
id_proceso=mi_proceso();
Es una forma de obtener su ID. Todos los procesos tienen también su ID en la variable local predefinida ID, que puedes copiarla en cualquier variable global que tengas.
Otra forma de obtener la ID es con:
id_proceso=get_id(type mi_proceso);
Que te devuelve la ID de un proceso cualquiera de ese tipo que exista (o cero si no hay). Si vuelves a llamar a GET_ID, te dará otra ID de otro proceso de ese tipo, hasta que te los diga todos (momento en el que empieza a devolver creo) o hagas un FRAME (que se reinicia y vuelve a darte de nuevo los valores desde el principio).
Pero lo mejor es obtener la ID de un proceso nada más crearlo. Ojo, esta asignación tiene lugar tras el FRAME del proceso creado (lo digo por si ese mismo proceso tiene que leer dicha variable, que aun valdrá cero o lo que valiese antes).
También puedes enviar señales como S_FREEZE (que detiene el proceso y muestra su gráfico, con sus características de size, angle y demás, que pueden modificarse desde otros procesos), S_SLEEP (que detiene el proceso y NO muestra su gráfico), S_WAKEUP (que despierta un proceso dormido/congelado), y sus variaciones _TREE, como S_KILL_TREE que mata a un proceso y todos aquellos que haya generado (sus hijos), o S_SLEEP_TREE, S_WAKEUP_TREE...
Reabro mi propio hilo, mas que ná porque no encuentro uno especifico que ponía ''procesos que se auto matan'' o algo asi y lo que voy a preguntar igual se responde solo...
¿como conseguir que un proceso se suicide?
Yo lo tengo asi y creo que es valido:
proces revienta()
private
int c;
begin
graph = 1;
for (c=1; c < 100; c++)
size++;
frame 25;
end
end
creo que si el proceso llega a su fin, se muere... de pena, ¿no?
Quote from: Futu-block on January 29, 2018, 11:02:40 PM
Reabro mi propio hilo, mas que ná porque no encuentro uno especifico que ponía ''procesos que se auto matan'' o algo asi y lo que voy a preguntar igual se responde solo...
¿como conseguir que un proceso se suicide?
Yo lo tengo asi y creo que es valido:
proces revienta()
private
int c;
begin
graph = 1;
for (c=1; c < 100; c++)
size++;
frame 25;
end
end
creo que si el proceso llega a su fin, se muere... de pena, ¿no?
Claro, en cuanto el proceso termina su bucle principal finaliza. Si no hubiera bucle principal el proceso terminaría tras ejecutar sus instrucciones.
Por otro lado y si no estoy confundido, en el caso de que no hubiera bucle principal o mejor dicho instruccion FRAME, lo más adecuado es utilizar una función en lugar de un proceso ya que te aseguras de que se complete antes de retornar al proceso padre que la invocó (creo recordar que esta era la diferencia). Pero vamos, esto es algo de hilar muy fino y por las preguntas que haces creo que no necesitas estos detalles.
Que yo recuerde, las únicas formas de que un proceso se suicide son las que ya se han dicho: que llegue al END del PROCESS, que se ejecute un RETURN (en cuyo caso, hablamos de una FUNCTION, y luego la drástica: SIGNAL(ID, S_KILL)
También le puedes decir que está siendo programada para un juego tuyo, creo que suele ser bastante eficaz :D :D :D
Lol,
if (process != Auto kill)
Process know is working in my game
End
Aprovechando el hilo quiero hacer una pregunta:
Si tengo dos procesos A y B donde B recibe un puntero de A para controlar cuando el proceso A muere, y A modifica el valor de la variable en el apartado onExit ¿le dará tiempo a B de enterarse?
PROCESS b(int *salir)
BEGIN
while((*salir) == 0)
FRAME;
END
END
PROCESS a()
PRIVATE
int salir;
END
BEGIN
salir = 0;
b(&salir);
LOOP
FRAME;
END
OnExit:
salir = 1;
END
...
signal_skill(id_a, s_kill);
...
Cual es mi duda: que lanzando un "signal(id a, S_KILL)" cuando el proceso b quiera comprobar la variable "*salir" el proceso A, A ya no exista y por tanto tenga punteros locos.
Es decir, una vez ejecutado "OnExit"¿se espera el proceso por así decirlo 1 frame, por si otros procesos debieran consultar datos antes de morirse?
Por las pruebas que he estado haciendo no he visto problemas en usar ese método así que parece que sí espera, lo cual es lo deseable al menos en mi caso, pero quiero estar totalmente seguro de estar haciendolo bien.
En un momento dado te puedes cerciorar con un exists, pregunta si existe, usas usas sus datos
Quote from: Futu-block on February 09, 2018, 11:05:38 AM
En un momento dado te puedes serciorar con un exists, pregunta si existe, usas usas sus datos
Si, se que hay maneras para saber si un proceso está vivo, pero esa no es la pregunta.
tu sabe, con los punteros me vuelvo loco ;)
Quote from: Arcontus on February 08, 2018, 11:08:07 PM
Aprovechando el hilo quiero hacer una pregunta:
Si tengo dos procesos A y B donde B recibe un puntero de A para controlar cuando el proceso A muere, y A modifica el valor de la variable en el apartado onExit ¿le dará tiempo a B de enterarse?
PROCESS b(int *salir)
BEGIN
while((*salir) == 0)
FRAME;
END
END
PROCESS a()
PRIVATE
int salir;
END
BEGIN
salir = 0;
b(&salir);
LOOP
FRAME;
END
OnExit:
salir = 1;
END
...
signal_skill(id_a, s_kill);
...
Cual es mi duda: que lanzando un "signal(id a, S_KILL)" cuando el proceso b quiera comprobar la variable "*salir" el proceso A, A ya no exista y por tanto tenga punteros locos.
Es decir, una vez ejecutado "OnExit"¿se espera el proceso por así decirlo 1 frame, por si otros procesos debieran consultar datos antes de morirse?
Por las pruebas que he estado haciendo no he visto problemas en usar ese método así que parece que sí espera, lo cual es lo deseable al menos en mi caso, pero quiero estar totalmente seguro de estar haciendolo bien.
¿Alguien sabe si esto es correcto?
Gracias por adelantado :)
no espera nada, el onexit se ejecuta inmediatamente... mira estos ejemplos...
ejemplo 1 (kill externo)
import "mod_say";
import "mod_proc";
import "mod_key";
process a()
begin
while(1)
say("A frame...");
frame;
say("A continua...");
end
onexit:
say("A muerto!");
end
process b()
begin
while(1)
say("B frame...");
frame;
say("B continua...");
end
onexit:
say("B muerto!");
end
private
pa, pb, i;
begin
pa = a();
pb = b();
for ( i = 0; i < 4; i++)
if ( i == 2 )
say("main kill B...");
signal(pb,s_kill);
end
say("main frame...");
frame;
say("main continua...");
end
let_me_alone();
end
resultado
Quote
A frame...
B frame...
main frame...
main continua...
main frame...
B continua...
B frame...
A continua...
A frame...
main continua...
main kill B...
main frame...
B muerto!
A continua...
A frame...
main continua...
main frame...
A continua...
A frame...
main continua...
A muerto!
ejemplo 2 (auto kill)
import "mod_say";
import "mod_proc";
import "mod_key";
process a()
private
i;
begin
while(1)
i++;
if ( i == 2 )
say("A auto kill...");
signal(id,s_kill);
end
say("A frame...");
frame;
say("A continua...");
end
onexit:
say("A muerto!");
end
process b()
begin
while(1)
say("B frame...");
frame;
say("B continua...");
end
onexit:
say("B muerto!");
end
private
pa, pb, i;
begin
pa = a();
pb = b();
for ( i = 0; i < 4; i++)
say("main frame...");
frame;
say("main continua...");
end
let_me_alone();
end
resultado:
Quote
A frame...
B frame...
main frame...
main continua...
main frame...
B continua...
B frame...
A continua...
A auto kill...
A muerto!
main continua...
main frame...
B continua...
B frame...
main continua...
main frame...
B continua...
B frame...
main continua...
B muerto!
tambien puedes compilar con -g y ejecutar con -d para ver el orden de ejecucion del codigo.
ejemplo 1 (con -g y -d)
Quote
Loading... mod_say.so
Loading... mod_proc.so
Loading... libsdlhandler.so
Loading... libkey.so
Loading... mod_key.so
>>> Instance:MAIN ProcID:65536 StackUsed:0/4096
onexit.prg:33 pa = a();
>>> Instance:A ProcID:65537 StackUsed:0/4096
onexit.prg:7 while(1)
onexit.prg:8 say("A frame...");
A frame...
onexit.prg:9 frame;
onexit.prg:34 pb = b();
>>> Instance:B ProcID:65538 StackUsed:0/4096
onexit.prg:19 while(1)
onexit.prg:20 say("B frame...");
B frame...
onexit.prg:21 frame;
onexit.prg:36 for ( i = 0; i < 4; i++)
onexit.prg:36 for ( i = 0; i < 4; i++)
onexit.prg:37 if ( i == 2 )
onexit.prg:41 say("main frame...");
main frame...
onexit.prg:42 frame;
>>> Instance:MAIN ProcID:65536 StackUsed:0/4096
onexit.prg:43 say("main continua...");
main continua...
onexit.prg:44 end
onexit.prg:36 for ( i = 0; i < 4; i++)
onexit.prg:36 for ( i = 0; i < 4; i++)
onexit.prg:37 if ( i == 2 )
onexit.prg:41 say("main frame...");
main frame...
onexit.prg:42 frame;
>>> Instance:B ProcID:65538 StackUsed:0/4096
onexit.prg:22 say("B continua...");
B continua...
onexit.prg:23 end
onexit.prg:19 while(1)
onexit.prg:20 say("B frame...");
B frame...
onexit.prg:21 frame;
>>> Instance:A ProcID:65537 StackUsed:0/4096
onexit.prg:10 say("A continua...");
A continua...
onexit.prg:11 end
onexit.prg:7 while(1)
onexit.prg:8 say("A frame...");
A frame...
onexit.prg:9 frame;
>>> Instance:MAIN ProcID:65536 StackUsed:0/4096
onexit.prg:43 say("main continua...");
main continua...
onexit.prg:44 end
onexit.prg:36 for ( i = 0; i < 4; i++)
onexit.prg:36 for ( i = 0; i < 4; i++)
onexit.prg:37 if ( i == 2 )
onexit.prg:38 say("main kill B...");
main kill B...
onexit.prg:39 signal(pb,s_kill);
onexit.prg:41 say("main frame...");
main frame...
onexit.prg:42 frame;
>>> Instance:B ProcID:65538 StackUsed:0/4096
>>> Instance:B ProcID:65538 StackUsed:0/4096
onexit.prg:25 say("B muerto!");
B muerto!
>>> Instance:A ProcID:65537 StackUsed:0/4096
onexit.prg:10 say("A continua...");
A continua...
onexit.prg:11 end
onexit.prg:7 while(1)
onexit.prg:8 say("A frame...");
A frame...
onexit.prg:9 frame;
>>> Instance:MAIN ProcID:65536 StackUsed:0/4096
onexit.prg:43 say("main continua...");
main continua...
onexit.prg:44 end
onexit.prg:36 for ( i = 0; i < 4; i++)
onexit.prg:36 for ( i = 0; i < 4; i++)
onexit.prg:37 if ( i == 2 )
onexit.prg:41 say("main frame...");
main frame...
onexit.prg:42 frame;
>>> Instance:A ProcID:65537 StackUsed:0/4096
onexit.prg:10 say("A continua...");
A continua...
onexit.prg:11 end
onexit.prg:7 while(1)
onexit.prg:8 say("A frame...");
A frame...
onexit.prg:9 frame;
>>> Instance:MAIN ProcID:65536 StackUsed:0/4096
onexit.prg:43 say("main continua...");
main continua...
onexit.prg:44 end
onexit.prg:36 for ( i = 0; i < 4; i++)
onexit.prg:36 for ( i = 0; i < 4; i++)
onexit.prg:46 let_me_alone();
>>> Instance:A ProcID:65537 StackUsed:0/4096
>>> Instance:A ProcID:65537 StackUsed:0/4096
onexit.prg:13 say("A muerto!");
A muerto!
ejemplo 2 (con -g y -d)
Quote
Loading... mod_say.so
Loading... mod_proc.so
Loading... libsdlhandler.so
Loading... libkey.so
Loading... mod_key.so
>>> Instance:MAIN ProcID:65536 StackUsed:0/4096
onexit.prg:40 pa = a();
>>> Instance:A ProcID:65537 StackUsed:0/4096
onexit.prg:9 while(1)
onexit.prg:10 i++;
onexit.prg:11 if ( i == 2 )
onexit.prg:15 say("A frame...");
A frame...
onexit.prg:16 frame;
onexit.prg:41 pb = b();
>>> Instance:B ProcID:65538 StackUsed:0/4096
onexit.prg:26 while(1)
onexit.prg:27 say("B frame...");
B frame...
onexit.prg:28 frame;
onexit.prg:43 for ( i = 0; i < 4; i++)
onexit.prg:43 for ( i = 0; i < 4; i++)
onexit.prg:44 say("main frame...");
main frame...
onexit.prg:45 frame;
>>> Instance:MAIN ProcID:65536 StackUsed:0/4096
onexit.prg:46 say("main continua...");
main continua...
onexit.prg:47 end
onexit.prg:43 for ( i = 0; i < 4; i++)
onexit.prg:43 for ( i = 0; i < 4; i++)
onexit.prg:44 say("main frame...");
main frame...
onexit.prg:45 frame;
>>> Instance:B ProcID:65538 StackUsed:0/4096
onexit.prg:29 say("B continua...");
B continua...
onexit.prg:30 end
onexit.prg:26 while(1)
onexit.prg:27 say("B frame...");
B frame...
onexit.prg:28 frame;
>>> Instance:A ProcID:65537 StackUsed:0/4096
onexit.prg:17 say("A continua...");
A continua...
onexit.prg:18 end
onexit.prg:9 while(1)
onexit.prg:10 i++;
onexit.prg:11 if ( i == 2 )
onexit.prg:12 say("A auto kill...");
A auto kill...
onexit.prg:13 signal(id,s_kill);
>>> Instance:A ProcID:65537 StackUsed:0/4096
onexit.prg:20 say("A muerto!");
A muerto!
>>> Instance:MAIN ProcID:65536 StackUsed:0/4096
onexit.prg:46 say("main continua...");
main continua...
onexit.prg:47 end
onexit.prg:43 for ( i = 0; i < 4; i++)
onexit.prg:43 for ( i = 0; i < 4; i++)
onexit.prg:44 say("main frame...");
main frame...
onexit.prg:45 frame;
>>> Instance:B ProcID:65538 StackUsed:0/4096
onexit.prg:29 say("B continua...");
B continua...
onexit.prg:30 end
onexit.prg:26 while(1)
onexit.prg:27 say("B frame...");
B frame...
onexit.prg:28 frame;
>>> Instance:MAIN ProcID:65536 StackUsed:0/4096
onexit.prg:46 say("main continua...");
main continua...
onexit.prg:47 end
onexit.prg:43 for ( i = 0; i < 4; i++)
onexit.prg:43 for ( i = 0; i < 4; i++)
onexit.prg:44 say("main frame...");
main frame...
onexit.prg:45 frame;
>>> Instance:B ProcID:65538 StackUsed:0/4096
onexit.prg:29 say("B continua...");
B continua...
onexit.prg:30 end
onexit.prg:26 while(1)
onexit.prg:27 say("B frame...");
B frame...
onexit.prg:28 frame;
>>> Instance:MAIN ProcID:65536 StackUsed:0/4096
onexit.prg:46 say("main continua...");
main continua...
onexit.prg:47 end
onexit.prg:43 for ( i = 0; i < 4; i++)
onexit.prg:43 for ( i = 0; i < 4; i++)
onexit.prg:49 let_me_alone();
>>> Instance:B ProcID:65538 StackUsed:0/4096
>>> Instance:B ProcID:65538 StackUsed:0/4096
onexit.prg:32 say("B muerto!");
B muerto!
respuesta... es incorrecto...
Ya veo lo que comentas SplinterGU, pero no es esa la pregunta y creo que es importante. A ver como lo explico.
Lo mas facil es verlo en el código que puse:
PROCESS b(int *salir)
BEGIN
while((*salir) == 0)
FRAME;
END
END
El proceso B seguira funcionando mientras su puntero salir valga 0. Salir pertenece al proceso A. Si B consulta el valor de salir de A cuando A no exista, el programa petará.
PROCESS a()
PRIVATE
int salir;
END
BEGIN
salir = 0;
b(&salir);
LOOP
FRAME;
END
OnExit:
salir = 1;
END
El proceso A, al recibir un signal S_KILL cambia el valor de salir a 1 para que el proceso B termine, pero realmente A llega antes a su END antes de que el proceso B pueda consultar la variable "salir".
...
signal_skill(id_a, s_kill);
...
Espero haberlo explicado con claridad el ejemplo.
El caso es que con todas las pruebas que he hecho, y son muchisimas, no he detectado que este sistema provoque inestabilidad o pete del programa, por lo que sin ver que sucede exactamente (a nivel interno de bennu me refiero), me atrevo a afirmar que el proceso "muerto", en realidad es mas bien un "zombie" donde sus variables de tipo PUNTERO siguen siendo perfectamente accesibles hasta que el resto de procesos alcancen el siguiente FRAME. Algo así como que para morir el proceso deba recorrer ciertas listas internas de bennu y ello conlleve esta accesibilidad temporal vinculada de alguna manera al FRAME. Pero claro, no puedo estar 100% seguro de que esto sea así.
Ojo, hablo de PUNTEROS es decir apuntadores de memoria, no de acceder a la estructura del proceso del tipo "father.salir" (para el caso de que salir fuera pública en vez de privada). Esto segundo seguro que no funciona, por que "father" ya está marcado para morir y bennu no dejaría recorrer su arbol de datos.
¿Me explico? ¿Es correcto?
En el caso que pone Splinter, lo que estamos observando es el cierre del proceso y como es lógico salen los SAY en el orden de ejecución, pero obviamente después de que un proceso alcanza ese END de final de proceso, la cosa no acaba ahi, sino que pasan cosas en las tablas de control de bennu y sus oscuros misterios misteriosos.
El quid es contestar si el código anterior es totalmente valido o si su uso genera inestabilidad (la cual repito no he visto).
Gracias por la paciencia, estoy muy interesado en desvelar este misterio. :)
no es valido... es solo suerte, es solo porque el area de memoria aun no ha sido reutilizada por nadie, pero es un area de datos que ya no pertenece a nadie, y esta liberada...
para demostrar lo que digo... agregue log a las funciones instance_new e instance_destroy (que son donde se alocan y liberan los bloques de memoria de las variables de los procesos):
Quote
instance_new
instance_new
A frame...
instance_new
B frame...
main frame...
main continua...
main frame...
B continua...
B frame...
A continua...
A frame...
main continua...
main kill B...
main frame...
B muerto!
B bye bye!
instance_destroy
A continua...
A frame...
main continua...
main frame...
A continua...
A frame...
main continua...
instance_destroy
A muerto!
A bye bye!
instance_destroy
como ves, el destroy use ejecuta antes que el 2do proceso se ejecute...
pero... podes hacer un truco para que esto sea seguro...
el truco esta en usar diferentes priority (mayor en el proceso con OnExit y menor en el que chequea el puntero) y frame en el OnExit...
la cosa seria algo asi...
PROCESS b(int *salir)
BEGIN
priority = father.priority - 1;
while((*salir) == 0)
FRAME;
END
END
PROCESS a()
PRIVATE
int salir;
END
BEGIN
salir = 0;
b(&salir);
LOOP
FRAME;
END
OnExit:
salir = 1;
frame;
END
el punto esta en que b() deberia tener una prioridad inferior que a(), y usar el frame, ahi si podrias hacer de forma segura lo que queres.
como detalle adicional, internamente, el motor tiene un loop que recorre todos los procesos y los ejecuta (solo ejecuta los que esten vivos y no hayan completado su frame o los que tengan estado killed o dead), cuando termina el loop, actualiza los contadores de porcentaje de frame completado y vuelve a hacer el loop... en este punto, segun lo que mencione antes, podemos darnos cuenta que los procesos vivos con su frame completo no se volveran a ejecutar, pero los que estan en dead o killed se volveran a ejecutar hasta que desparezcan... una vez que el loop detecta que no ejecuto ningun proceso, ahi es donde se completa realmente el FRAME de todos los procesos y reinicia el ciclo... por eso, un proceso killeado, por mas frame que tenga, se resuelve en el frame que murio... cuando el FRAME es completado el proceso no existe mas...
tambien podes simplemente hacer esto...
PROCESS b()
BEGIN
LOOP
FRAME;
END
END
PROCESS a()
PRIVATE
int pb;
END
BEGIN
pb = b();
LOOP
FRAME;
END
OnExit:
signal(pb,s_kill);
END
o
signal(id_a, s_kill_tree);
que mata a A y a su descendencia.
Gracias SplinterGU, muy aclaratorio.
Respecto a lo que comentas del priority, no veo en que caso puede "mejorar" ya que en mi ejemplo, hasta que no alcanza onExit: no realiza el cambio en la variable "salir", por lo que la prioridad con la que se ejecuten los procesos daría lo mismo.
Respecto a s_kill_tree, tengo una duda: si un proceso tiene más de un hijo, y este a su vez tiene más de un nieto, tengo entendido que este sistema solo recorre una única linea, en concreto la última linea de creación de hijos ¿no es cierto? De todas formas, no es exactamente lo que necesito.
Pues vaya problemón... ¿No se podría (digo yo) hacer que FRAME; dentro de OnExit: se comportara igual que siempre, y asi se pueden sincronizar procesos en su defuncion?
Actualmente FRAME dentro de OnExit: es FRAME(0), lo cual no entiendo muy bien el motivo e impide por ejemplo abordar este "problema" con esta solución. Tampoco es el fin del mundo, ya que se puede hacer de una manera algo más tediosa, pero seria genialisimo poder sincronizar cosas antes de que los procesos murieran.
Gracias,
Un saludo!
la prioridad si te servira, porque hara que el OnExit del proceso A se ejecute antes que el proceso B... con lo que te aseguras que "salir" exista y no estes apuntando a un area de memoria fantasma o ocupada por otro nuevo proceso...
por otro lado, ya me adelante a lo que me preguntaste y ya estoy probando un cambio para hacer que FRAME dentro de OnExit, se comporte igual que en otras partes del codigo.
pero de paso estoy arreglando otras cosas que tienen que ver con esa parte de la logica y se relacionan con el debugger.
Quote from: SplinterGU on February 14, 2018, 04:26:10 PM
por otro lado, ya me adelante a lo que me preguntaste y ya estoy probando un cambio para hacer que FRAME dentro de OnExit, se comporte igual que en otras partes del codigo.
pero de paso estoy arreglando otras cosas que tienen que ver con esa parte de la logica y se relacionan con el debugger.
Que gran noticia!! La verdad es que este cambio simplificaría el uso de OnExit.
Un saludo!
Yo te recomendaría que no te complicases tanto. Eso de un puntero para salir es muy "C".
Si quieres salir de una parte del código, he comprobado que las dos mejores soluciones son las siguientes:
- Tener un proceso de control que sea el encargado de decidir quié vive y quién muere, y en qué orden.
- Que "salir" y todas las variables que sean conflictivas en el orden de ejecución, sean variables globales, y que cada proceso reaccione cuando pueda (es interesante porque de esta forma, el proceso que ponga la variable "salir" a "true" tiene un valor de priority, y cada proceso independiente el suyo propio, que se ejecutará en el mismo frame si son más lentos, o en el siguiente si son más rápidos).
En cualquier caso, intenta evitar en todo lo posible punteros a variables internas de procesos. Puedes usar las locals o las public sin pegas porque tienes EXISTS para comprobar que el proceso aun existe. En cualquier otro caso, recomendaría que las varibles fuesen globales.
Por ejemplo, si necesitas crear 4 procesos con datos de altura, peso y edad, no uses variables privadas, usa un array dinámico (o lista enlazada) con un tipo que te hayas creado tu, y que tenga otra variable con el ID del proceso que lo ha creado. De esta forma, cualquier proceso puede buscar si existe el nodo del proceso xxx, y el propio proceso xxx podría tener un puntero privado directo al nodo.
Quote from: Drumpi on May 07, 2018, 01:04:20 AM
Yo te recomendaría que no te complicases tanto. Eso de un puntero para salir es muy "C".
Si quieres salir de una parte del código, he comprobado que las dos mejores soluciones son las siguientes:
- Tener un proceso de control que sea el encargado de decidir quié vive y quién muere, y en qué orden.
- Que "salir" y todas las variables que sean conflictivas en el orden de ejecución, sean variables globales, y que cada proceso reaccione cuando pueda (es interesante porque de esta forma, el proceso que ponga la variable "salir" a "true" tiene un valor de priority, y cada proceso independiente el suyo propio, que se ejecutará en el mismo frame si son más lentos, o en el siguiente si son más rápidos).
En cualquier caso, intenta evitar en todo lo posible punteros a variables internas de procesos. Puedes usar las locals o las public sin pegas porque tienes EXISTS para comprobar que el proceso aun existe. En cualquier otro caso, recomendaría que las varibles fuesen globales.
Por ejemplo, si necesitas crear 4 procesos con datos de altura, peso y edad, no uses variables privadas, usa un array dinámico (o lista enlazada) con un tipo que te hayas creado tu, y que tenga otra variable con el ID del proceso que lo ha creado. De esta forma, cualquier proceso puede buscar si existe el nodo del proceso xxx, y el propio proceso xxx podría tener un puntero privado directo al nodo.
Después de 5 años peleandome con Bennu, te doy la razón en que este modo es muy "C" y de que no es la mejor manera tal y como está estructurado el tema del FRAME en el OnExit, pero a veces es lo que más conviene. Y no me voy a pegar el rollo poniendo ejemplos ya que también utilizo tus soluciones para unos casos, pero para otros lo tengo que hacer de esta manera.
También estarás de acuerdo conmigo de que si FRAME en OnExit funcionara como en el resto del código, a: sería más claro para todo desarrollador que empiece (yo me enteré hace relativamente poco y por que me petaba una cosa del proyecto) y b: ya daría igual como decidas controlar los procesos. Tendrias libertad para hacer lo que más te conveniera.
En resumen: Hoy por hoy si no quieres tener problemas, haced lo que dice Drumpi, pero sería mejor no tener esa "limitación".
Quote from: Arcontus on May 08, 2018, 04:26:39 PM
Quote from: Drumpi on May 07, 2018, 01:04:20 AM
Yo te recomendaría que no te complicases tanto. Eso de un puntero para salir es muy "C".
Si quieres salir de una parte del código, he comprobado que las dos mejores soluciones son las siguientes:
- Tener un proceso de control que sea el encargado de decidir quié vive y quién muere, y en qué orden.
- Que "salir" y todas las variables que sean conflictivas en el orden de ejecución, sean variables globales, y que cada proceso reaccione cuando pueda (es interesante porque de esta forma, el proceso que ponga la variable "salir" a "true" tiene un valor de priority, y cada proceso independiente el suyo propio, que se ejecutará en el mismo frame si son más lentos, o en el siguiente si son más rápidos).
En cualquier caso, intenta evitar en todo lo posible punteros a variables internas de procesos. Puedes usar las locals o las public sin pegas porque tienes EXISTS para comprobar que el proceso aun existe. En cualquier otro caso, recomendaría que las varibles fuesen globales.
Por ejemplo, si necesitas crear 4 procesos con datos de altura, peso y edad, no uses variables privadas, usa un array dinámico (o lista enlazada) con un tipo que te hayas creado tu, y que tenga otra variable con el ID del proceso que lo ha creado. De esta forma, cualquier proceso puede buscar si existe el nodo del proceso xxx, y el propio proceso xxx podría tener un puntero privado directo al nodo.
Después de 5 años peleandome con Bennu, te doy la razón en que este modo es muy "C" y de que no es la mejor manera tal y como está estructurado el tema del FRAME en el OnExit, pero a veces es lo que más conviene. Y no me voy a pegar el rollo poniendo ejemplos ya que también utilizo tus soluciones para unos casos, pero para otros lo tengo que hacer de esta manera.
También estarás de acuerdo conmigo de que si FRAME en OnExit funcionara como en el resto del código, a: sería más claro para todo desarrollador que empiece (yo me enteré hace relativamente poco y por que me petaba una cosa del proyecto) y b: ya daría igual como decidas controlar los procesos. Tendrias libertad para hacer lo que más te conveniera.
En resumen: Hoy por hoy si no quieres tener problemas, haced lo que dice Drumpi, pero sería mejor no tener esa "limitación".
creo que ese cambio ya lo libre... sino, esta en el horno... viene a fuego lento... asi que habra que esperar... estoy cambiando cosas del core relacionadas con el debugger... bah, hay cambios en el debugger, callbacks del core, y otras cosas...
Yo espero que nadie se haya ofendido con la frase de "es muy "C"".
Lo que venía a decir es que todos los que empezamos con un lenguaje nuevo, venimos acostumbrados a una forma de programar, y tendemos a usar lo que conocemos. Nos cuesta entender que la filosofía es diferente y hay que cambiar radicalmente el chip. A mi me pasó hace 5 años cuando me enfrenté a Unity (orientado a usar el editor gráfico), y me está pasando ahora con Xamarin y su MVVM.
No vais a encntrar nada más diferente que Bennu en cuestión de lenguajes. Vienes acostumbrado a que creas un método, termina y empieza otro. Aquí los vas creando y no se eliminan... y eso significa que van a chocar entre sí, a competir por los recursos, que las respuestas se pueden atrasar un frame por el orden de ejecución, y que un proceso que parece que está ahí de pronto ¡puf! no está.
Yendo al hilo: el OnExit tiene su significado, y lo he entendido después de varios años. Está para cerrar el proceso. No para matar a un enemigo con una animación de na explosión espectacular, no, sino, literalmente, para matar AL PROCESO.
Quiero decir, que no tiene sentido usar FRAME dentro, para nada.
El OnExit está para que al eliminar un proceso, especialmente si lo matan con un SIGNAL(xx, S_KILL) tengamos la oportunidad de descargar sus gráficos, sonidos o liberar sus punteros. De otra forma, necesitaríamos un proceso de control externo que se percate de su muerte y haga la liberación de recursos por él... o tener sus recursos fuera de dicho proceso (en estructuras en listas enlazadas globales, en variables globales...).
Si quieres tener una animación para matar a un enemigo, es mejor que tengas una variable local ENERGIA y hagas algo así:
process enemigo (x, y, energia)
private
int pointer hijos;
begin
//inicializaciones
while (energia > 0)
//nave moviéndose
//nave disparando
frame;
end
for (graph = ini_explosión; graph < fin_explosion; graph++)
frame;
end
prota.puntos += 10;
on_exit
for (i = 0; i < max_hijos; i++)
signal(hijos[ i], S_KILL);
end
end
Y ahora sí, me retiro a dormir, que mañana sigo programando en VB6, C# y SQL Server/Hana.
Quote from: Drumpi on May 11, 2018, 12:57:55 AM
Yo espero que nadie se haya ofendido con la frase de "es muy "C"".
¿En serio?, ¡que va, al contrario!, me parece un alago y yo no lo hubiera definido mejor. :D
¡Uy! Eso es que entonces eres muy novato :D :D :D
No, en serio, hay muchísimos programadores que se molestan si les comparas su código con otros lenguajes, especialmente si no les gusta. Si hay algo que he visto en común en muchos programadores, es su nivel de frikismo por encima de 3/10, un nivel bajo de autismo, y un alto nivel de instinto territorial y de ego. Por suerte, eso por aquí no abunda mucho... pero yo soy friki de nivel 4, no soy muy de relacionarme (parezco más vasco que andaluz), tengo mis manías, y mi ego se dispara cuando hablo de mis criaturas binarias :D
para mi tambien es un halago... van 2 novatos... :D