signal question

  • fox_hound_33
  • Newbie
  • Newbie
  • No Avatar
  • Inscription: Mai 26, 2008
  • Messages: 5
  • Status: Offline

Message Mai 26th, 2008, 10:03 pm

Bonjour tous,

Je commence à apprendre le traitement du signal dans Linux et d'avoir essayé quelques codes simples pour faire face à SIGALRM. Le code montré ci-dessous présente une minuterie pour le compte à rebours. Lorsque le compteur est fini un SIGALRM est produite. Le gestionnaire pour le signal simplement des tranches d'un nombre variable appelée. Cette opération est répétée jusqu'à ce q la touche 'i' dans le clavier. Le code est montré ci-dessous:

-------------------------------------------------- ----------
Code: [ Select ]
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#include <stdlib.h>

void my_action(int);

int count = 0;

int main(int argc, char** argv)
{
    struct sigaction sigalrm_action;
    struct itimerval timer;
    
    timer.it_interval.tv_sec = 0; //Deal only in usec
    timer.it_interval.tv_usec = 1000;
    timer.it_value.tv_sec = 0; //Deal only in usec
    timer.it_value.tv_usec = 1000;

    sigalrm_action.sa_handler = my_action;
    sigemptyset(&sigalrm_action.sa_mask);
    sigalrm_action.sa_flags = 0;
    
    sigaction(SIGALRM, &sigalrm_action, 0);            

    printf("Hit any key to start, q to exit\n");    
    getchar();
        
    if(setitimer(ITIMER_REAL, &timer,NULL) != 0){
        perror("Error starting timer");
        exit(1);
    } 
    while(getchar()!= 'q');
    printf("Bye bye\n");
    return 0;
}

void my_action(int signum)
{
    count++;
    printf("Count is %d\n", count);
}
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <signal.h>
  4. #include <sys/time.h>
  5. #include <stdlib.h>
  6. void my_action(int);
  7. int count = 0;
  8. int main(int argc, char** argv)
  9. {
  10.     struct sigaction sigalrm_action;
  11.     struct itimerval timer;
  12.     
  13.     timer.it_interval.tv_sec = 0; //Deal only in usec
  14.     timer.it_interval.tv_usec = 1000;
  15.     timer.it_value.tv_sec = 0; //Deal only in usec
  16.     timer.it_value.tv_usec = 1000;
  17.     sigalrm_action.sa_handler = my_action;
  18.     sigemptyset(&sigalrm_action.sa_mask);
  19.     sigalrm_action.sa_flags = 0;
  20.     
  21.     sigaction(SIGALRM, &sigalrm_action, 0);            
  22.     printf("Hit any key to start, q to exit\n");    
  23.     getchar();
  24.         
  25.     if(setitimer(ITIMER_REAL, &timer,NULL) != 0){
  26.         perror("Error starting timer");
  27.         exit(1);
  28.     } 
  29.     while(getchar()!= 'q');
  30.     printf("Bye bye\n");
  31.     return 0;
  32. }
  33. void my_action(int signum)
  34. {
  35.     count++;
  36.     printf("Count is %d\n", count);
  37. }

-------------------------------------------------- --------

Le problème est que je suis confronté à cela, quand je régler la minuterie pour 1000000usec ça marche (ie fine 1sec). Toutefois, si je continue à réduire le temps d'USEC à 100000, 10000, 1000 etc Le moment semble être trop lent. La variable count est incrémenté pas aussi vite qu'il devrait l'être. Pourquoi est-ce que c'est? J'ai l'impression que je fais une erreur stupide ici, mais je ne suis pas sûr de ce qu'il est.

Toute aide serait grandement appréciée.
  • Anonymous
  • Bot
  • No Avatar
  • Inscription: 25 Feb 2008
  • Messages: ?
  • Loc: Ozzuland
  • Status: Online

Message Mai 26th, 2008, 10:03 pm

  • casablanca
  • Proficient
  • Proficient
  • Avatar de l’utilisateur
  • Inscription: Mai 29, 2007
  • Messages: 481
  • Status: Offline

Message Mai 26th, 2008, 11:39 pm

Je ne peux que penser de deux raisons possibles de votre problème:

1. Peut-être que la méthode par laquelle on mesure l'intervalle de temps est mauvais. I / O des fonctions telles que printf généralement assez longue à exécuter, donc à des intervalles inférieurs à rebours, votre timer de feu plus vite que cela prendrait un printf à compléter.

2. Im ne savez pas comment setitimer est mis en œuvre, mais généralement, le système d'exploitation gère l'aide de minuteries interruptions. Le timer interrupt généralement tous les feux de quelques millisecondes, afin thats probablement le plus petit intervalle de n'importe quelle application peut compter à rebours.
No Strings Attached: A JavaScript graphics demo.
  • fox_hound_33
  • Newbie
  • Newbie
  • No Avatar
  • Inscription: Mai 26, 2008
  • Messages: 5
  • Status: Offline

Message Mai 27th, 2008, 12:26 am

casablanca a écrit:
Je ne peux que penser de deux raisons possibles de votre problème:

1. Peut-être que la méthode par laquelle on mesure l'intervalle de temps est mauvais. I / O des fonctions telles que printf généralement assez longue à exécuter, donc à des intervalles inférieurs à rebours, votre timer de feu plus vite que cela prendrait un printf à compléter.

---> Il est possible que printf prend trop de temps comme vous l'avez dit mais je ne peux pas imaginer printf prendre plus de 10 ms (le problème commence quand je régler la minuterie de 10 ms ou moins). Toute idée de combien de temps prend printf?


2. Im ne savez pas comment setitimer est mis en œuvre, mais généralement, le système d'exploitation gère l'aide de minuteries interruptions. Le timer interrupt généralement tous les feux de quelques millisecondes, afin thats probablement le plus petit intervalle de n'importe quelle application peut compter à rebours.

---> J'ai pensé à cela aussi. Existe-t-il aucun moyen de savoir quelle est la plus petite résolution timer à la disposition de l'OS?

  • casablanca
  • Proficient
  • Proficient
  • Avatar de l’utilisateur
  • Inscription: Mai 29, 2007
  • Messages: 481
  • Status: Offline

Message Mai 27th, 2008, 1:14 am

fox_hound_33 a écrit:
Toute idée de combien de temps prend printf?

Vous pouvez obtenir une estimation en utilisant la fois la fonction avant et après votre printf.

fox_hound_33 a écrit:
Existe-t-il aucun moyen de savoir quelle est la plus petite résolution timer à la disposition de l'OS?

Im pas trop sûr. Comme il existe des fonctions comme le sommeil usleep qui prennent un argument en microsecondes, il doit y avoir une autre manière par laquelle l'OS calcule fois.
No Strings Attached: A JavaScript graphics demo.
  • fox_hound_33
  • Newbie
  • Newbie
  • No Avatar
  • Inscription: Mai 26, 2008
  • Messages: 5
  • Status: Offline

Message Mai 27th, 2008, 2:51 am

Qu'est-ce que je rassemble des pages de manuel, est que toute fonction du temps (sommeil (), usleep (), settimer etc) ne sera jamais expire précisément à la valeur de point, il expire peu après.

J'ai couru un code de test en utilisant usleep et trouvé quelques résultats intéressants.
Quand j'ai mis à 0.1secs usleep, la durée du sommeil varie du point (0.1secs) avec une erreur d'environ 5%. La même erreur pourcentage grimpe à environ 40% quand j'ai mis usleep 0.01sec à la même erreur et passe à environ 300 %(!!!!) lorsque j'ai mis à usleep 0.001sec.

On dirait que la minuterie est amené à la résolution de l'erreur ne cesse d'augmenter. Pourrait être dû au système de minuterie de résolution comme indiqué. Cela pourrait expliquer pourquoi settimer a un comportement étrange pour les faibles valeurs de temps.

ou peut-être il ya une autre raison ??????????
  • casablanca
  • Proficient
  • Proficient
  • Avatar de l’utilisateur
  • Inscription: Mai 29, 2007
  • Messages: 481
  • Status: Offline

Message Mai 27th, 2008, 3:18 am

fox_hound_33 a écrit:
une fonction du temps (sommeil (), usleep (), settimer etc) ne sera jamais expire précisément à la valeur de point, il expire peu après.

Oui, parce que l'appelant thats fil sera mis en sommeil, et il sera réveillé que lors de la prochaine contexte passer après le délai expire. Alors que votre approche de l'intervalle de minuterie contexte switch intervalle, l'erreur va augmenter. De commutation et le contexte général est lui-même dépendant de l'interruption de minuterie, ce qui vous allez. :)

En dehors de la minuterie, le mécanisme de signalisation pourrait être un autre goulot d'étranglement potentiel, c'est-à-dire la rapidité avec laquelle le gestionnaire de signal est appelée après un signal est élevée.
No Strings Attached: A JavaScript graphics demo.
  • Daemonguy
  • Moderator
  • Web Master
  • Avatar de l’utilisateur
  • Inscription: Jan 23, 2004
  • Messages: 2673
  • Loc: Somewhere outside the box in Sarasota, FL.
  • Status: Offline

Message Mai 27th, 2008, 1:07 pm

Je serais enclin à d'accord avec l'évaluation précitée, l'opération est plus long que le délai lui causant ainsi un retard de la sortie.
"It's always a long day, 86,400 won't fit into a short."
  • Mc_Gregor
  • Born
  • Born
  • No Avatar
  • Inscription: Déc 02, 2008
  • Messages: 1
  • Status: Offline

Message Décembre 2nd, 2008, 3:44 pm

Salut tout le monde ..
Je souhaite utiliser le setitimer pour exécuter une minuterie dans un cycle d'une durée de quelques lignes et je suis plus que livré avec elle .. quelqu'un pourrait me donner un coup de main? ..

Code: [ Select ]
struct itimerval val;

val.it_interval.tv_sec = 0;
val.it_interval.tv_usec = interv;

val.it_value.tv_sec = 0;
val.it_value. tv_usec = interv;
setitimer (ITIMER_VIRTUAL, & val, NULL);

for (i = 0; i <can not; i + +)

(
sentences to run ..
)
  1. struct itimerval val;
  2. val.it_interval.tv_sec = 0;
  3. val.it_interval.tv_usec = interv;
  4. val.it_value.tv_sec = 0;
  5. val.it_value. tv_usec = interv;
  6. setitimer (ITIMER_VIRTUAL, & val, NULL);
  7. for (i = 0; i <can not; i + +)
  8. (
  9. sentences to run ..
  10. )


L'idée est que les peines de courir un peu et repartir après avoir fini votre chronomètre jusqu'au début du cycle ..
J'apprécie l'aide ..

Afficher de l'information

  • Total des messages de ce sujet: 8 messages
  • Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 61 invités
  • Vous ne pouvez pas poster de nouveaux sujets
  • Vous ne pouvez pas répondre aux sujets
  • Vous ne pouvez pas éditer vos messages
  • Vous ne pouvez pas supprimer vos messages
  • Vous ne pouvez pas joindre des fichiers
 
 

© 2011 Unmelted, LLC. Ozzu® est une marque déposée de Unmelted, LLC