void on_alarm(int signum){
call_function();if(!done)
alarm(delay_in_seconds);//Reschedule alarm}...//Setup on_alarm as a signal handler for the SIGALRM signalstruct sigaction act;
act.sa_handler =&on_alarm;
act.sa_mask =0;
act.sa_flags = SA_RESTART;//Restart interrupted system calls
sigaction(SIGALRM,&act, NULL);
alarm(delay_in_seconds);//Setup initial alarm
Bien sûr, ces deux méthodes ont le problème que la fonction que vous appelez doit périodiquement être thread-safe.
Le signal de la méthode est particulièrement dangereuse, car elle doit aussi être async-sûr, ce qui est très dur à faire, même une chose aussi simple que printf est dangereux parce que les printf peut allouer de la mémoire, et si le SIGALRM interrompu un appel à malloc, vous êtes en difficulté, parce que malloc n'est pas réentrant. Donc, je ne recommanderais pas le signal de la méthode, à moins que tous vous avez à faire est de définir un indicateur dans le gestionnaire de signal qui plus tard devient vérifié par une autre fonction, ce qui vous fait revenir au même endroit que la version letée.
Le problème est que j'utilise la SDL et parce que, quand j'appuie sur le bouton de sortie, il faudra patienter jusqu'à ce que la boucle se fait (qui gèle aussi à la demande). Ex. for(i = 0; i < 5; i++) { sleep(1) }
Il y a de divers legs de façons de le faire à l'aide de compteurs d'intervalle et de signaux, mais je vais présenter deux approches modernes:
À l'aide de POSIX minuteries
POSIX timer_create fonction crée une minuterie qui peut être configuré pour fournir une ponctuelle ou périodique de notification lors de l'expiration de la minuterie. Lors de la création de la minuterie, vous pouvez demander la livraison par l'intermédiaire d'un signal ou dans un nouveau thread. Depuis l'utilisation de signaux correctement est compliqué (il y a des règles strictes sur ce que vous pouvez et ne pouvez pas le faire à partir d'un gestionnaire de signal, et de briser les règles souvent "semble fonctionner", jusqu'à ce que vous obtenez malheureux), je recommande l'utilisation de thread basée à la livraison.
Rouler votre propre compteur avec un fil
C'est vraiment aussi facile qu'il y paraît. De faire un nouveau thread qui va dans une boucle de dormir et de faire ce que vous devez faire à chaque fois que l'heure souhaitée s'est écoulé.
De l'OMI, dans ce cas, vous pouvez utiliser gettimeofday() dans l'algorithme comme:
l'utilisation d'une telle while(1) qui compte de la différence de temps entre l'heure actuelle et last_execution_time, à chaque fois que la différence atteindre les 1 secondes, mise à jour de la last_execution_time et d'appeler la fonction qui censé fonctionner dans toutes les 1 seconde.
Dans le cas où vous avez besoin de thread différent de thread principal, déplacer les lignes de l'intérieur() un pointeur de fonction et le passer à travers pthread_create fonction, par exemple :
void*threadproc(void*arg){while(1){//put the same lines as inside main() function in above code snippet. .}}
pthread_create(&tid, NULL,&threadproc, NULL);
Vous pourriez générer un nouveau thread:
Ou, vous pouvez définir une alarme avec
alarme(2)
ousetitimer(2)
:Bien sûr, ces deux méthodes ont le problème que la fonction que vous appelez doit périodiquement être thread-safe.
Le signal de la méthode est particulièrement dangereuse, car elle doit aussi être async-sûr, ce qui est très dur à faire, même une chose aussi simple que
printf
est dangereux parce que lesprintf
peut allouer de la mémoire, et si leSIGALRM
interrompu un appel àmalloc
, vous êtes en difficulté, parce quemalloc
n'est pas réentrant. Donc, je ne recommanderais pas le signal de la méthode, à moins que tous vous avez à faire est de définir un indicateur dans le gestionnaire de signal qui plus tard devient vérifié par une autre fonction, ce qui vous fait revenir au même endroit que la version letée.OriginalL'auteur Adam Rosenfield
Il y a de divers legs de façons de le faire à l'aide de compteurs d'intervalle et de signaux, mais je vais présenter deux approches modernes:
À l'aide de POSIX minuteries
POSIX
timer_create
fonction crée une minuterie qui peut être configuré pour fournir une ponctuelle ou périodique de notification lors de l'expiration de la minuterie. Lors de la création de la minuterie, vous pouvez demander la livraison par l'intermédiaire d'un signal ou dans un nouveau thread. Depuis l'utilisation de signaux correctement est compliqué (il y a des règles strictes sur ce que vous pouvez et ne pouvez pas le faire à partir d'un gestionnaire de signal, et de briser les règles souvent "semble fonctionner", jusqu'à ce que vous obtenez malheureux), je recommande l'utilisation de thread basée à la livraison.Rouler votre propre compteur avec un fil
C'est vraiment aussi facile qu'il y paraît. De faire un nouveau thread qui va dans une boucle de dormir et de faire ce que vous devez faire à chaque fois que l'heure souhaitée s'est écoulé.
OriginalL'auteur R..
De l'OMI, dans ce cas, vous pouvez utiliser
gettimeofday()
dans l'algorithme comme:l'utilisation d'une telle
while(1)
qui compte de la différence de temps entre l'heure actuelle et last_execution_time, à chaque fois que la différence atteindre les 1 secondes, mise à jour de la last_execution_time et d'appeler la fonction qui censé fonctionner dans toutes les 1 seconde.Dans le cas où vous avez besoin de thread différent de thread principal, déplacer les lignes de l'intérieur() un pointeur de fonction et le passer à travers pthread_create fonction, par exemple :
OriginalL'auteur Asmoro Glenmore