c - teorema - submuestreo de una señal
Señales simples-Programación en C y función de alarma. (4)
Andomar está en lo cierto. Pruebo esto y, la versión 1 imprime (cada segundo):
Hi...
Hi...
Hi...
Hi...
BYE
Hi...
...
La versión 2 imprime (cada cinco segundos):
Hi...Hi...Hi...Hi...BYE
Hi...Hi...Hi...Hi...BYE
...
Entonces el código es:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
# define T 5
int flag = T;
void sigalrm_handler(int);
int main(void)
{
signal(SIGALRM, sigalrm_handler);
alarm(1);
while (1);
}
void sigalrm_handler(int sig)
{
if(--flag){
printf("Hi.../n"); /*version 1*/
/*printf("Hi...");*/ /*version 2*/
}else{
printf("BYE/n");
flag=T;
}
alarm(1);
}
#include <stdio.h>
#include <signal.h>
void ALARMhandler(int sig)
{
signal(SIGALRM, SIG_IGN); /* ignore this signal */
printf("Hello");
signal(SIGALRM, ALARMhandler); /* reinstall the handler */
}
int main(int argc, char *argv[])
{
alarm(2); /* set alarm clock */
while (1)
;
printf("All done");
}
Espero que el programa imprima "hola" después de 2 segundos, pero en su lugar, la salida es "zsh: alarm ./a.out"
¿Alguna idea de lo que está pasando?
No está instalando el manejador de señales primero.
Debe decirle al sistema que desea manejar la señal antes de recibirla, por lo que debe llamar a la signal()
desde la línea principal antes de que llegue la señal.
int main(int argc, char *argv[])
{
signal(SIGALRM, ALARMhandler); /* install the handler */
alarm(2); /* set alarm clock */
while (1);
}
No estás configurando el controlador en tu función main
.
Antes de hacer la alarm(2)
, ponga la signal(SIGALRM, ALARMhandler);
en tu main
Debería funcionar entonces.
Tenga en cuenta que su "All Done" nunca se imprimirá, porque permanecerá en el bucle while (1) después de que se haya ejecutado el procesador de señales. Si desea que el bucle se rompa, deberá tener una marca que cambie el manejador de señales.
#include <stdio.h>
#include <signal.h>
/* number of times the handle will run: */
volatile int breakflag = 3;
void handle(int sig) {
printf("Hello/n");
--breakflag;
alarm(1);
}
int main() {
signal(SIGALRM, handle);
alarm(1);
while(breakflag) { sleep(1); }
printf("done/n");
return 0;
}
Te olvidaste de configurar el controlador de alarma inicialmente. Cambiar el inicio de main()
como:
int main(int argc, char *argv[])
{
signal(SIGALRM, ALARMhandler);
...
Además, el manejador de señales probablemente no imprima nada. Esto se debe a que la biblioteca C almacena en caché la salida hasta que ve un final de línea. Asi que:
void ALARMhandler(int sig)
{
signal(SIGALRM, SIG_IGN); /* ignore this signal */
printf("Hello/n");
signal(SIGALRM, ALARMhandler); /* reinstall the handler */
}
Para un programa del mundo real, la impresión desde un controlador de señales no es muy segura. Un manejador de señales debería hacer lo menos posible, preferiblemente solo estableciendo una bandera aquí o allá. Y la bandera debe ser declarada volatile
.