Je suis en train de développer un logiciel simple pour vérifier si je peux programmer en utilisant ce que j'ai étudié sur les timers et les signaux POSIX.Gestion des temporisateurs POSIX et des signaux POSIX
Je suis en train de faire un programme simple qui démarre une minuterie et émet un signal d'une certaine quantité de nanosecondes
Le programme suivant ne I fonctionne pas bien, donc écrit des commentaires sur mon code afin que vous puissiez vérifier si J'ai correctement étudié ou non. Vous pouvez trouver la liste complète des codes au bas de la page.
Divers tirages comme
prinf("1\n")doivent vérifier où le programme se termine prématurément. J'ai mis
struct sigevent sigeventStructcomme structure pour les événements d'expirations générés par le temporisateur. Le premier paramètre est défini sur SIGEV_SIGNAL, c'est donc le type de signal qu'il émettra. /// Les différents memset que vous pouvez lire dans la liste de code sont à zéro structures initialisées.
if(timer_create(_POSIX_MONOTONIC_CLOCK, &sigeventStruct, &timer1) == -1)
est de créer un temporisateur POSIX. POSIX MONOTONIC CLOCK est le type de temporisateur, & sigeventStruct est le pointeur vers la structure qui décrit comment c'est l'événement généré par l'expiration du temporisateur. Timer1 est le pointeur sur le nom du temporisateur spécifique. & Avec cette procédure, le temporisateur est armé, de sorte que vous pouvez le faire générer des expirations. Timer1 est le nom de la minuterie, 0 est les drapeaux. Le livre GAPIL dit: <> & tempoIniziale et & tempoFinale sont des pointeurs vers les structures itimerspec. Je n'ai pas bien compris quelle est la signification de & old_timer. Dans le livre GAPIL vous pouvez lire: <>
struct sigaction, oldSigAzione
structs sigaction qui sera passé en paramètre à sigaction gestionnaire de signaux Posix
sigaction (SIGEV_SIGNAL, NULL, &oldSigAzione)
SIGEV_SIGNAL est le genre de signaux qu'il doit gérer, NULL est où il pourrait être placé un pointeur vers une sigaction de structure const, & oldSigAzione est le pointeur vers la structure de sigaction que j'ai mentionnée auparavant. Là encore je n'ai pas compris la différence entre ces deux pointeurs vers la structure de sigaction.
Ma question est: pourquoi le programme se termine avant d'imprimer le numéro 19 de printf ("19 \ n"); et pourquoi n'exécute pas le printf ("Timer scaduto \ n"); à l'intérieur de la fonction void termination_handler (int signum)?
Voici mon code:
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/fcntl.h>
#include <sys/wait.h>
#include <stdbool.h>
void termination_handler(int signum)
{
printf("Timer scaduto\n");
}
int main()
{
printf("Start\n");
printf("1\n");
struct sigevent sigeventStruct; // sigevent struct that will be used by timer1 timer
printf("2\n");
memset(&sigeventStruct, 0, sizeof sigeventStruct); // zero initialize struct
printf("3\n");
sigeventStruct.sigev_notify = SIGEV_SIGNAL; // kind of notification of timer1 expiration
printf("4\n");
sigeventStruct.sigev_signo = 10;
printf("5\n");
timer_t timer1; // create a timer identifier
printf("6\n");
if(timer_create(_POSIX_MONOTONIC_CLOCK, &sigeventStruct, &timer1) == -1)
{
printf("Errore timer_create: %s\n", strerror(errno));
}
printf("7\n");
struct itimerspec tempoIniziale;
printf("8\n");
memset(&tempoIniziale, NULL, sizeof tempoIniziale); // zero initialize struct
printf("9\n");
tempoIniziale.it_value.tv_nsec = 100000000;
//tempoIniziale.it_interval.tv_nsec = 10000;
printf("10\n");
if(timer_settime(timer1, 0, &tempoIniziale, NULL) == -1) // timer armed
{
printf("Errore timer_settime: %s\n", strerror(errno));
}
printf("11\n");
for(int i = 0; i< 10; i++)
{
printf("ciclo %d\n", i);
}
struct sigaction oldSigAzione;
printf("12\n");
memset(&oldSigAzione, 0, sizeof oldSigAzione);
printf("13\n");
oldSigAzione.sa_handler = termination_handler;
printf("14\n");
sigemptyset (&oldSigAzione.sa_mask);
printf("15\n");
oldSigAzione.sa_flags = 0;
printf("16\n");
sigaction (SIGEV_SIGNAL, NULL, &oldSigAzione);
printf("17\n");
if(oldSigAzione.sa_handler == SIG_IGN)
{
printf("Segnale ignorato\n");
}
printf("18\n");
for(int i = 0; i < 1000000000000; i++)
{
}
printf("19\n");
printf("number of expirations %d\n", timer_getoverrun(timer1));
return 0;
}
Une boucle vide n'est pas le moyen de retarder. Un compilateur moderne le compilera sans code du tout. Essayez 'sleep' ... –
De plus,' printf' n'est pas sûr pour les signaux asynchrones. Vous ne pouvez pas l'utiliser depuis un gestionnaire de signal à moins d'éviter tous les appels à des fonctions asynchrones dans le code qui pourraient être interrompues par le signal. –