[C con Clase] Duda

Manuel L. notret en gmx.es
Lun Ene 10 17:19:01 CET 2011


Hola, memmaker650. Deseo que, a pesar de la tardanza, mi respuesta siga siendo útil.
 
m> Buenas de nuevo.
m> ... Lo que hace captura_frame es crear una alarma para cada dos minutos llamar a metodo_fuego para que haga el tratamiento de unos datos.
m> ...
m> El problema es que me parece que no será exactamente cada 120 segundos porque hay que tener en cuenta el tiempo de tratamiento de los datos.  

En efecto.

m> ...
m> Para que fuera cada 120 segundos debería usar hilos de ejecución o un fork y que el hijo ejecutará metodo_fuego y el padre siguiera en el bucle infinito ???
m> Alguna otra opción.
m> 
m> Un saludo.

Si lo piensa bien, su solución...

void captura_frame() {
  almacen <int> v(1);
  signal(SIGALRM, metodo_fuego);
  while(1) {
    alarm(120);
    pause();
  }
}

... se aproxima mucho a lo que desea hacer. El problema está en que tan pronto establece la cuenta atrás detiene el programa en espera de la cuenta, quedando el proceso los 120 minutos ocioso. En el medio tendría que transcurrir la ejecución de metodo_fuego... sea pues:

#include <stdio.h>
#include <signal.h>

void CODIGO_IRRELEVANTE(int _) {};
void procesar() { printf("Procesando...\n"); }

int main() {
  signal(SIGALRM,CODIGO_IRRELEVANTE);
  while(1) {
    alarm(3);
    procesar();
    pause();
  }
  return 0;
}

Otra opción igualmente válida sería la siguiente:

#include <stdio.h>
#include <signal.h>

void procesar() { printf("Procesando...\n"); }
void manejadorAlrm(int _) { alarm(3); procesar(); }

// Procedimientos definidos para facilitar la lectura del main
void inicializarPrograma() {
  signal(SIGALRM,manejadorAlrm);
  manejadorAlrm(SIGALRM);
}
int bucleDeEventos() { while(1) pause(); return 0; }

int main() {
  inicializarPrograma();
  // ...
  return bucleDeEventos();
}

En esta opción hace que el manejador sea el que se encargue de establecer una nueva alarma y luego procesar. Ambas son opciones válidas, pero no iguales. En la primera le da protagonismo al bucle de eventos al situarlo en main (primer plano). Es lectura obligada. Imagínese que no fuese importante, sino rutinario y posiblemente no interesase ni tocar. Un suponer, los repetitivos eventos de redibujar una ventana, atender a los periféricos (ratón, teclado...), etc. Lo puede esconder elegantemente en el manejador. Llámele a inicializarPrograma initGUI y a bucleDeEventos mainLoopEvent. ¿Ve por dónde voy? Así el programador se fija menos en la implementación de esos eventos (en el ejemplo importa más qué se hace con los eventos o cómo es la interfaz).

Finalmente quisiera recordarle que signal es una función contrarrecomendada. Además de por motivos de portabilidad, se ha quedado obsoleta. Se recomienda el uso de sigaction. Consulte las páginas del manual (man signal, man sigaction) si tiene alguna duda al respecto.

Atentamente, Manuel L.


Más información sobre la lista de distribución Cconclase