Orden de muerte al matar con S_KILL_TREE

Started by Windgate, September 30, 2009, 05:49:35 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Windgate

Acabamos de comprobar que S_KILL_TREE mata procesos recorriendo el árbol en profundidad. ¿Hay alguna forma de especificar que queremos matar recorriendo el árbol en anchura? ¿O el comportamiento es siempre el mismo?

Asias!
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

splinter_work

tree es un tree... no entiendo a que llamas anchura...

Drumpi

Desde tiempos de DIV, s_kill_tree mata a un proceso, a sus hijos, a los hijos de susu hijos, a los hijos de los hijos de sus hijos y así en bucle loop.
¿Matar en anchura significa matar a sus hermanos?
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

Windgate

Me refiero al orden de muerte, y lo pregunto por simple curiosidad.

Supongamos un padre A con 2 hijos B y C.

B tiene un hijo llamado X y C tiene un hijo llamado Z.

Si matamos en profundidad vamos de cada raiz hacia arriba, morirían en este orden:

X - B - Z - C - A

En cambio si matamos en anchura vamos subiendo niveles desde la raiz, moriría en este orden:

X - Z - B - C - A

La teoría de árboles nos dice que para recorrer un árbol se pueden seguir varios métodos, los más fáciles de implementar son profundidad y anchura, pero había unos cuantos más.

Esta tarde haciendo unas pruebas hemos descubierto que la muerte en árbol iba en profundidad, es complicado de explicar... Es como si en el caso anterior el proceso X invocase un proceso A... X mandaba una señal a A y moría X, luego B, luego A y ya no se podía seguir matando a C y Z porque quedaban huérfanos...

En anchura no hubiese pasado eso... Me ha parecido curioso y he concluido que Bennu mata un árbol recorriéndolo en profundidad.

PD: Siento machacaros el cerebro con una cosa tan rara, al final evitando que el proceso X invocase un proceso A convirtiendo el árbol en un grafo se ha solucionado todo el problema, el árbol moría sin que sucediese nada "raro".
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

SplinterGU

no, imposible, son ramas de arboles diferentes... eso no suena logico para nada.

podes matar hermanos, recorriendolos desde un nodo...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Windgate

¿Quieres decir entonces que la muerte en anchura es imposible, verdad? (Al menos sin complicar excesivamente la cosa...)

Ciertamente la Jerarquía Bennu (father, son) está hecha para recorrerse en profundidad, no en anchura :P

Aclaración resuelta y las S_XXX_TREE actuan en profundidad.

Gracias.
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Drumpi

Hombre, más que nada creo que es porque estas funciones funcionan por recursividad, algo así como:

process matar(id_proceso)
hijo=id_proceso.son;
while (hijo!=0)
matar(hijo);
hijo=id_proceso.son;
end

signal (id_proceso,s_kill);
end


Obviamente, cada vez que se invoca al proceso matar, el primero espera a que se ejecute el recién creado, por eso funciona como funciona. Te lo he puesto en código PseudoBennu para que lo analices tranquilamente.
Hacerlo en anchura, como dices, es mucho más complejo, y dado que todo el arbol va a morir en el mismo frame (incluso no va a dar tiempo a ejecutar otros procesos), debería dar igual el orden en que desaparezcan ¿no?
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

Windgate

Drumpi, entiendo tu código, ¿Entonces se mata desde el padre hacia los hijos? Eso había pensado que era al revés por cómo había programado en su día recorridos de árbol... Pero para el caso tanto da.

No hay problema en casos normales, pero nosotros teníamos una jerarquía de procesos que no era un árbol, era un grafo, me explico a groso modo:

Teníamos un proceso crear_escenario que primero mataba a todo bicho viviente con S_KILL_TREE y luego invocaba toda la fauna y flora del juego.

El problema era que uno de los personajitos era el encargado de volver a invocar a crear_escenario, por lo que teníamos un "bucle", la señal de muerte perseguía a los procesos por el grafo y terminaba matando al propio proceso crear_escenario, y a sus hijos, y...

Hemos observado que cuando ocurría eso algunos procesos quedaban vivos, y hemos concluído en que la señal avanzaba en profundidad, "se saltaba algunas ramas" porque se quedaba en ese bucle del grafo, nada más.

Como he dicho (No sé si me he explicado todo lo bien que debía), después de evitar el grafo todo iba bien y no importaba en absoluto el orden de muertes, como debe ser.

Con esto quiero decir que todo está en orden y la duda resuelta, se puede cerrar el hilo si queréis, como siempre un placer dialogar con ustedes, thanks.
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Drumpi

No, no, lo has entendido al revés: va matando de los hijos al padre, pero se distribuye desde el padre a los hijos. Fíkate que se llama a sí mismo, un hijo más abajo ANTES de ejecutar el signal, así que el signal sólo se ejecuta cuando no tiene hijos o los procesos muerte que invoca han terminado.
Es como los procesos: al llamar a un proceso, este no se ejecuta al llegar al frame, interrumpe al padre y se ejecuta hasta su propio frame, y luego el padre sigue su ejecución normal.
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

Windgate

Oh, es recursivo, que no me había fijado, entonces es como lo que programé sobre árboles en su día, se llegaba al nodo sin hijos y desde ahí se "trabajaba la estructura".

Ok, todo claro, dejemos la conclusión para cerrar el hilo:

S_XXX_TREE recorre el árbol de procesos en profundidad y afecta desde los hijos (Nodos hoja) hacia la raiz.
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

FreeYourMind

Reabro.

No me esta funcionando el s_kill_tree....

Ejemplo, en el main:

Pinto una imagen en pantalla llamando a a(), que dentro de si pinta la imagen llamando a b() (es b() quien pinta la imagen con un loop frame; end), pues sólo desaparece la imagen si mato directamente a b(), si mato a a() no desaparece y si mato a a() con kill_tree tampoco...


signal(type a, s_kill); // a() muere (eso creo) pero su hijo b() se mantiene
signal(type b, s_kill); // Funciona, b() muere, a() se mantiene vivo (eso creo)
signal(type a, s_kill_tree); // --> Error: a() muere (eso creo), pero b() que es su hijo se mantiene vivo

DjSonyk

Humm, ¿crees o estas seguro?,yo hecho miles de pruebas y todos los signal me funciona bien,hacen lo que espero que haga, ¿Seguro que b() se crea dentro de a()?
No estaria mal que pusieras el codigo ^^

BoMbErLiNk

Has probado signal(id, s_kill_tree); / signal(id_proceso, s_kill_tree); ?

FreeYourMind

#13
Es que no se el id del proceso, por eso pongo type, en realidad son muchos iguales que quiero matar.

Bueno, ya he asignado el id y tampoco funciona:

PRIVATE
ft;

BEGIN

LOOP

             say(ft);

   IF (ft != 0)
      signal(ft, s_kill_tree);
   END

   ft = a();

FRAME;
END

Esto tampoco mata los hijos de a(), que son los procesos b().

DjSonyk

Prueba esto...[code language="bennu"]program skilltree;

import "mod_proc";
import "mod_grproc";
import "mod_say";


private
   int ft;
   int estadob;
end

process a()

   begin
      b();
      loop
         frame;
      end
   end

process b()

   begin
      say("b creado "+id);   
      loop
         frame;
      end
   end

begin
   ft = a();
   loop

        say(ft);
      
      if ( ft!=0 )
         signal(ft, s_kill_tree);
      //   signal(ft, s_kill);   //alternar con la sentencia de arriba para ver los cambio
         say("muerte de a");
         estadob=get_id(type b);
         if ( estadob!=0 )
            say("b esta vivo "+estadob);
         else
            say("b tambien a muerto "+estadob);
         end
         
      end
      estadob=0;
      ft = a();

      frame;
   end
end[/code]