web-dev-qa-db-fra.com

mettre en œuvre le délai dans c

Je ne sais pas exactement comment trouver une recherche dans ce mot .. donc je n'ai pas eu de chance de trouver quoi que ce soit ..:

J'ai besoin d'implémenter un délai en C.

par exemple, je veux faire des choses, puis attendre une minute, puis continuer à faire des choses.

Cela avait-il du sens? Quelqu'un peut m'aider?

27
developer

Voici comment vous pouvez le faire sur la plupart des systèmes de bureau:

#ifdef _WIN32
    #include <windows.h>
#else
    #include <unistd.h>
#endif

void wait( int seconds )
{   // Pretty crossplatform, both ALL POSIX compliant systems AND Windows
    #ifdef _WIN32
        Sleep( 1000 * seconds );
    #else
        sleep( seconds );
    #endif
}

int
main( int argc, char **argv)
{
    int running = 3;
    while( running )
    {   // do something
        --running;
        wait( 3 );
    }
    return 0; // OK
}

Voici comment vous pouvez le faire sur un micro-ordinateur/processeur sans minuterie:

int wait_loop0 = 10000;
int wait_loop1 = 6000;

// for microprocessor without timer, if it has a timer refer to vendor documentation and use it instead.
void
wait( int seconds )
{   // this function needs to be finetuned for the specific microprocessor
    int i, j, k;
    for(i = 0; i < seconds; i++)
    {
        for(j = 0; j < wait_loop0; j++)
        {
            for(k = 0; k < wait_loop1; k++)
            {   // waste function, volatile makes sure it is not being optimized out by compiler
                int volatile t = 120 * j * i + k;
                t = t + 5;
            }
        }
    }
}

int
main( int argc, char **argv)
{
    int running = 3;
    while( running )
    {   // do something
        --running;
        wait( 3 );
    }
    return 0; // OK
}

Les variables waitloop doivent être ajustées. Celles-ci ont fonctionné assez étroitement pour mon ordinateur, mais l’échelle de fréquence le rend très imprécis pour un système de bureau moderne; Donc, ne l'utilisez pas sauf si vous êtes nu et ne faites pas ce genre de choses.

15
Frank

Consultez la page de manuel check sleep (3) ou MSDN for Sleep

9
user180100

Bien que de nombreuses implémentations aient la fonction time renvoyer l’heure actuelle en secondes, il n’existe aucune garantie que chaque implémentation le fera (par exemple, certaines peuvent renvoyer millisecondes plutôt que secondes). En tant que tel, une solution plus portable consiste à utiliser la fonction difftime .

difftime est garanti par le standard C pour renvoyer la différence de temps en secondes entre deux valeurs time_t. En tant que tel, nous pouvons écrire une fonction de délai portable qui fonctionnera sur toutes les implémentations conformes de la norme C.

#include <time.h>

void delay(double dly){
    /* save start time */
    const time_t start = time(NULL);

    time_t current;
    do{
        /* get current time */
        time(&current);

        /* break loop when the requested number of seconds have elapsed */
    }while(difftime(current, start) < dly);
}

Un inconvénient avec les fonctions time et difftime est que le standard C ne spécifie jamais une granularité. La plupart des implémentations ont une granularité de une seconde. Même si cela convient pour des retards de plusieurs secondes, notre fonction de retard peut attendre trop longtemps avant que les retards de moins d’une seconde.

Il existe une alternative portable standard en C: la fonction clock.

La fonction clock renvoie la meilleure approximation de la durée du processeur utilisée par le programme depuis le début d’une ère définie par celle-ci qui ne concerne que l’appel du programme. Pour déterminer le temps en secondes, la valeur renvoyée par la fonction clock doit être divisée par la valeur de la macro CLOCKS_PER_SEC.

La solution de fonction clock est assez similaire à notre solution de fonction time:

#include <time.h>

void delay(double dly){
    /* save start clock tick */
    const clock_t start = clock();

    clock_t current;
    do{
        /* get current clock tick */
        current = clock();

        /* break loop when the requested number of seconds have elapsed */
    }while((double)(current-start)/CLOCKS_PER_SEC < dly);
}

Dans ce cas, une mise en garde similaire à celle de time et difftime: la granularité de la fonction clock est laissée à l'implémentation. Par exemple, les machines avec des valeurs 32 bits pour clock_t avec une résolution de microsecondes peuvent finir par encapsuler la valeur renvoyée par clock après 2147 secondes (environ 36 minutes).

En tant que tel, envisagez d'utiliser les implémentations time et difftime de la fonction de délai pour les retards de au moins une seconde, et l'implémentation de clock pour les retards de moins d'une seconde.

Un dernier mot d'avertissement: clock renvoie heure du processeur plutôt que heure du calendrier; clock peut ne pas correspondre au temps écoulé réel (par exemple, si le processus est en veille). 

6
Vilhelm Gray

sleep() est un bon choix pour les retards pouvant atteindre une minute.

Si, un jour, vous souhaitez suspendre les retards inférieurs à une seconde, vous pouvez envisager d'utiliser poll() avec un délai.

Les deux sont POSIX.

3
mouviciel

Essayez sleep(int number_of_seconds)

1
waffle paradox

sleep(int) fonctionne comme un bon délai. Pour une minute:

//Doing some stuff...
sleep(60); //Freeze for A minute
//Continue doing stuff...
1
thyrgle

Il n'y a pas de fonction sleep() dans la bibliothèque standard C, mais POSIX fournit quelques options.

La fonction POSIX sleep() (unistd.h) prend un argument unsigned int pour le nombre de secondes pendant lequel vous souhaitez vous mettre en veille. Bien qu'il ne s'agisse pas d'une fonction de la bibliothèque standard, elle est largement disponible et glibc semble la prendre en charge même lors de la compilation avec des paramètres plus stricts tels que --std=c11.

La fonction POSIX nanosleep() (time.h) prend deux pointeurs sur les structures timespec en tant qu'arguments et permet un contrôle plus précis de la durée de veille. Le premier argument spécifie la durée du délai. Si le deuxième argument n'est pas un pointeur nul, il conserve le temps restant si l'appel est interrompu par un gestionnaire de signal.

Les programmes qui utilisent la fonction nanosleep() devront peut-être inclure une macro de test feature pour pouvoir compiler. L'exemple de code suivant ne compilera pas sur mon système Linux sans une macro de test de fonctionnalité lorsque j'utilise un appel de compilation typique de gcc -std=c11 -Wall -Wextra -Wpedantic.

Une fois, POSIX avait un usleep() function (unistd.h) qui prenait un argument useconds_t pour spécifier la durée de veille en microsecondes. Cette fonction nécessitait également une macro de test de fonctionnalité lorsqu'elle était utilisée avec des paramètres de compilateur stricts. Malheureusement, usleep() est devenu obsolète avec POSIX.1-2001 et ne doit plus être utilisé. Il est recommandé d’utiliser nanosleep() maintenant au lieu de usleep().

#define _POSIX_C_SOURCE  199309L     // feature test macro for nanosleep()

#include <stdio.h>
#include <unistd.h>    // for sleep()
#include <time.h>      // for nanosleep()

int main(void)
{
    // use unsigned sleep(unsigned seconds)
    puts("Wait 5 sec...");
    sleep(5);

    // use int nanosleep(const struct timespec *req, struct timespec *rem);
    puts("Wait 2.5 sec...");
    struct timespec ts = { .tv_sec = 2,          // seconds to wait
                           .tv_nsec = 5e8 };     // additional nanoseconds
    nanosleep(&ts, NULL);
    puts("Bye");

    return 0;
}
1
David Bowling
0
ruslik

vous pouvez simplement appeler la fonction delay (). Donc, si vous voulez retarder le processus de 3 secondes, appelez le délai (3000) ... 

0
Owen

Si vous êtes certain de vouloir attendre et de ne jamais être interrompu, utilisez sleep en POSIX ou Sleep in Windows. Dans POSIX, le sommeil prend du temps en secondes. Par conséquent, si vous souhaitez que le temps soit plus court, il existe des variétés telles que usleep() qui utilise des microsecondes. Le sommeil dans Windows prend des millisecondes, il est rare que vous ayez besoin d'une granularité plus fine que celle.

Il se peut que vous souhaitiez attendre une période mais que vous souhaitiez autoriser des interruptions, peut-être en cas d'urgence. le sommeil peut être interrompu par des signaux, mais il existe un meilleur moyen de le faire dans ce cas.

Par conséquent, j’ai trouvé dans la pratique que vous attendiez un événement ou une variable de condition avec un délai d’attente.

Sous Windows, votre appel est WaitForSingleObject. Dans POSIX, c'est pthread_cond_timedwait.

Dans Windows, vous pouvez également utiliser WaitForSingleObjectEx, puis "interrompre" votre thread avec n'importe quelle tâche en file d'attente en appelant QueueUserAPC. WaitForSingleObject (Ex) renverra un code déterminant la cause de sa fermeture. Vous saurez ainsi, lorsqu'il renvoie le statut "TIMEDOUT", que le délai a bien été dépassé. Vous définissez l'événement qu'il attend quand vous voulez qu'il se termine.

Avec pthread_cond_timedwait, vous pouvez signaler la diffusion de la variable de condition. (Si plusieurs threads attendent sur le même, vous devrez émettre pour les réveiller tous). Chaque fois qu'il boucle, il devrait vérifier l'état. Votre thread peut obtenir l'heure actuelle et voir si elle est passée ou s'il peut vérifier si certaines conditions ont été remplies pour déterminer quoi faire. Si vous avez une sorte de file d'attente, vous pouvez la vérifier. (Votre thread aura automatiquement un mutex verrouillé utilisé pour attendre la variable de condition. Ainsi, lorsqu'il vérifiera la condition, il n'y aura qu'un accès).

0
CashCow