2010-10-25 38 views
1

Je veux exécuter une boucle infinie pendant un certain temps. Fondamentalement, je veux avoir quelque chose comme çaExécuter une boucle infinie pendant un certain temps dans c

//do something 

while(1){ 
    //do some work 
} 

//do some other thing 

, mais je veux le temps de fonctionnement de la boucle à fixer, par exemple, la boucle pourrait être en cours d'exécution pendant 5 secondes. Est-ce que quelqu'un a une idée?

+2

Besoin de plus d'informations, y at-il une raison pour laquelle vous ne pouvez pas simplement dormir? – user318904

+0

Peut être nécessaire pour une application en temps réel. Je ne fais que spéculer. –

+11

Le titre est un oxymore :) –

Répondre

9

Juste faire sleep(5) (inclure unistd.h). Vous pouvez l'utiliser comme ceci:

// do some work here 
someFunction();  

// have a rest 
sleep(5); 

// do some more work 
anotherFunction(); 

Si vous faites travail à l'intérieur de la boucle, vous pouvez faire (y compris time.h):

// set the end time to the current time plus 5 seconds 
time_t endTime = time(NULL) + 5; 

while (time(NULL) < endTime) 
{ 
    // do work here. 
} 
+0

Gardez à l'esprit que la boucle 'while' prendra * au moins * 5 secondes, peut prendre plus de 5 secondes si le travail dans la boucle prend beaucoup de temps. – dreamlax

+0

c'est intéressant, mais je ne veux pas faire un appel système à l'intérieur de la boucle 0e –

+0

@the_drug: Y at-il une raison pourquoi? – dreamlax

9

Essayez d'utiliser l'horloge().

#include <time.h> 

clock_t start = clock(); 

while (1) 
{ 
    clock_t now = clock(); 
    if ((now - start)/CLOCKS_PER_SEC > 5) 
     break; 

    // Do something 
} 
+1

'clock()' renvoie la quantité de temps processeur utilisée, pas le temps réel. – dreamlax

0

Pseudo-code:

starttime = ...; 

while(currentTime - startTime < 5){ 

} 
0

Non testé; la résolution est très grossière.

#include <time.h> 
#define RUNTIME 5.0 /* seconds */ 

double runtime = 0; 
double start = clock(); /* automatically convert clock_t to double */ 
while (runtime < RUNTIME/CLOCKS_PER_SEC) { 
    /* work */ 
    runtime = clock() - start; 
} 

Si/* travail */prend plus de 5 secondes, la boucle prendra plus de 5 secondes.

Si/* travail */prend 1,2 secondes, la boucle exécutera environ 5 fois pour un total de 6 secondes

+0

Juste curieux, pourquoi utiliser un 'double' et pas' clock_t'? – dreamlax

+0

Parce que 'clock_t' est un" type arithmétique ". Il n'y a aucune garantie qu'il peut contenir des valeurs fractionnaires (par exemple: 0.5) ... et je me sens mieux en utilisant '' double's – pmg

+0

Aussi, après avoir parcouru la [spec] pertinente (http://www.opengroup.org/onlinepubs/ 009695399/functions/clock.html) il apparaît que 'clock()' retournera la quantité de temps processeur utilisée, pas en temps réel. – dreamlax

1

Tout d'abord, pensez à utiliser la fonction sleep si possible. Si vous devez faire un travail réel pour une période de temps déterminée, que je trouve peu probable, la solution laide suivante fonctionnerait:

#include <signal.h> 
int alarmed = 0; 
void sigh(int signum) { 
    alarmed = 1; 
} 
int main(void){ 
    /* ... */ 
    signal(SIGALRM, &sigh); 
    alarm(5); // Alarm in 5 seconds 
    while(!alarmed) { 
     /* Do work */ 
    } 
    /* ... */ 
} 

Une solution à l'aide time.h serait également possible, et peut-être plus simple et/ou plus précis, selon le contexte:

#include <time.h> 
int main(void){ 
    /* ... */ 
    clock_t start = clock(); 
    while(clock() - start < 5 * CLOCKS_PER_SEC) { 
     /* Do work */ 
    } 
    /* ... */ 
} 
+0

Cela devrait être 'void sigh (int signum)', non? –

+0

la première solution est celle que j'utilise actuellement. Le fait est que je dois utiliser des variables "volatiles" dans ma boucle, sinon elles sont perdues. Mais l'utilisation de variables volatiles ralentit ma boucle. –

+0

@Oli: Il devrait. Je vais éditer maintenant - n'a pas vraiment prêté attention la nuit dernière;) – You

0

Si vous ne voulez pas appeler un temps à la fonction à chaque fois dans la boucle et sont sur un système qui a alarm (POSIXes comme Unix, Linux, BSD ...) vous pouvez faire:

statique volatil e int timeout = 0;

void handle_alrm(int sig) { 
    timeout = 1; 
} 

int main(void) { 
    signal(SIGALRM, handle_alrm); 
    ... 
    timeout = 0; 
    alarm(5); 
    while (!timeout) { 
     do_work(); 
    } 
    alarm(0); // If the signal didn't fire yet we can turn it off now. 
    ... 

Les signaux peuvent avoir d'autres effets secondaires (comme vous empêcher de passer des appels système). Vous devriez regarder dans ces derniers avant de les compter.

+0

Est-ce que le timeout doit réellement être volatile? Et si c'est le cas, devrait-il s'agir d'un 'sig_atomic_t'? Je demande parce que chaque fois que je fais quelque chose avec des signaux, je dois toujours regarder à nouveau tout ... –

+0

Dans ce contexte, je voudrais utiliser les deux; Je peux faire valoir que l'un ou l'autre d'entre eux sont inutiles, mais ils ne feront aucun mal et ils pourraient sauver votre cul. – zwol

+0

@Steve: J'allais le faire 'sig_atomic_t' mais j'ai pensé" qui pourrait ne pas être disponible sur Windows "et j'ai oublié de revenir en arrière et de le changer quand j'ai réalisé que' alarm' pourrait ne pas être disponible là non plus. – nategoose