IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

pause de durée paramètrable dans une boucle


Sujet :

C++

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    164
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 164
    Points : 161
    Points
    161
    Par défaut pause de durée paramètrable dans une boucle
    bonjour, je recherche un moyen de faire une pause de durée paramètrable (en milliseconde de préférence) dans une boucle for ou while, ma boucle va parcourir un tableau d'images que je veux afficher plus ou moins rapidement.
    le programme donnerai à peu près ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    for(int i=0;i<taille;i++)
    {
         afficher(tab[i]);
         pause(500); //ici ma pause de 500ms
    }
    y a t-il une telle fonction dans les librairies de bases?

    merci de vos réponses

  2. #2
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    Bonjour,

    la fonction sleep() est disponible sur la plupart des systèmes et permet de mettre en pause un thread.

    Toutefois, j'imagine que si tu affiches des images tu dois disposer d'un GUI. Hors, si l'on met en pause le thread qui s'occupe du GUI, l'interface graphique va aussi être "gelée".

    Il faut alors mettre en place un programme multi-thread où on ne mettera en pause que le thread chargé d'afficher les images, sans que cela gèle l'interface utilisateur.

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    164
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 164
    Points : 161
    Points
    161
    Par défaut
    je n'ai peut etre pas donné suffisamment de précision, il s'agit d'un programme de type MFC avec une fonction d'affichage écrite à la main (utilisation de StretchDIBits).
    la fonction sleep() va t-elle bloquer tout l'affichage?
    j'ai essayé de l'utiliser dans un programme tout simple, mais la fonction n'est pas reconnue :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #include <iostream>
    #include "stdlib.h"
    #include "time.h"
     
    using namespace std;
     
    void main(){
    	for(int i=0;i<5000;i++)
    	{
    		cout<<i<<" ";
    		sleep(2000);
    	}
    }
    faut-il inclure d'autres librairies ?

  4. #4
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Points : 1 543
    Points
    1 543
    Par défaut
    Salut,

    Dans l'API Windows c'est Sleep avec au besoin windows.h à inclure si ce n'est pas déjà fait dans ton application.

    MAT.
    ps: en français on dit une bibliothèque et non une librairie (c'est ce qu'on appelle un faux ami)

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    164
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 164
    Points : 161
    Points
    161
    Par défaut
    salut, même en incluant la bibliothèque winows.h la fonction sleep n'est toujours pas reconnue

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #include <iostream>
    #include <windows.h>
     
    using namespace std;
     
    void main(){
    	for(int i=0;i<5000;i++)
    	{
    		cout<<i<<" ";
    		sleep(2000);
    	}
    }
    error C3861: 'sleep' : identificateur introuvable
    help!!

  6. #6
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Points : 1 543
    Points
    1 543
    Par défaut
    Avec un S majuscule.

    MAT.

  7. #7
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Neitsa Voir le message
    Il faut alors mettre en place un programme multi-thread où on ne mettera en pause que le thread chargé d'afficher les images, sans que cela gèle l'interface utilisateur.
    Rhaaaaaa

    vous m'énervez avec vos threads et multi-threads....

    Un peu d'imagination, que diable !!!!

    Un exemple en C :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    *
     *  F S l e e p 
     *
     */
    static void  FSleep ( Interface_Data *idata, double Secs, 
                          int Acceleraion, int t_start, void *UpdateDipslay(void*) )
    {
      int                      Statut,  s ;
      clock_t                  Saved_Clock, Actual_Clock, Clock1000 ;
      double                   diff, MilliSecs, Secs_Demandees, Clocks_Per_MilliSec ;
      time_t                   t_verif ;
      struct tm               *Saved ;
      
      if ( Secs <= 0.0 ) return ;
     
    
    /*
    --- Calcule combien de millisecondes on doit attendre
    */
      if ( Acceleration > 0 )
          Secs_Demandees = Secs / (double)(Acceleration) ;
      else
          Secs_Demandees = 3600 ;
    
      Clocks_Per_Millisec = (double)CLOCKS_PER_SEC / 1000.0 ;
    
      MilliSecs = (double)( (int)(Secs_Demandees * 1000.) ) ;
      if ( t_start != -1 )
        {
            t_verif = t_start ;
            Saved = gmtime((time_t *)&t_verif) ;
        }
    
      Statut = 0 ;
      Saved_Clock = clock();
      Clock1000 = Saved_Clock ;
    
    /*
    --- Attend ce nombre, et verifie toute les secondes si on n'a pas
        interrompu l'attente
    */
      while ( Statut != 1 )
       {
            UpdateDisplay ( (void *)idata ); /* ICI on appelle  la fonction d'update à chaque passe */
    
            Actual_Clock = clock();
            diff = (double)(Actual_Clock - Saved_Clock) / Clocks_Per_MilliSec ;
    
            if ( diff >= MilliSecs ) /* ici on a fini l'attente */
               {
                   break ;
               }
    
    /*
    --- Chaque seconde
    */
            if ( (double)((Actual_Clock - Clock1000)/Clocks_Per_MilliSec) >= 1000.0 )
              {
                   Clock1000 = Actual_Clock ; 
                   /* Verifie certains paramètres */
                  /* Si attente interrompue (par flag ou autre) sort */
              }
            else
              {
                   if ( Acceleration == 0 ) /* Si on s'est mis en "pause", vérifie quand même chaque seconde */
                         sleep (1);
    
                   /* sinon boucle et va mettre à jour le GUI à chaque CYCLE d'horloge */
              }
       }
    }

  8. #8
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    vous m'énervez avec vos threads et multi-threads....

    Un peu d'imagination, que diable !!!!
    Donc, si j'ai bien compris, pour ne pas faire de multithread, tu remplaces ça par une attente active, qui bouffe toutes les ressources de la machine, consomme plein d'électricité et fait dégager au processeur tout plein de chaleur sans autre but que d'accélérer le réchauffement climatique ?

  9. #9
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut


    parce que tu crois que ça ne fait pas ça avec des threads ?????????


    et je te signale que ça ne fait pas plus d'attente active que le MainLoop de l'outil graphique, puisque c'est celui-ci qu'on appelle quand on fait "Update_Display"..

    Plus précisément, le MainLoop fait DispatchEvent
    Eh bien cette routine que dans l'exemple j'ai appelée Update_Display fait ça...

    C'est tout...

    ça permet de faire de l'attente dans un GUI sans que le GUI gèle, et de manière portable...et sans avoir besoin de s'em...er avec des threads...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    static void Update_Display ( void *data )
    {
    Interface_Data *idata = (Interface_Data *)data ;
     
        DispatchEvent(idata); /* Pour avoir les éléments graphiques */
    }
    j'aimerais bien que tu m'expliques comment tu penses que ça marche, un gestionnaire graphique....



    Si tu m'en trouves un qui ne fonctionne pas suivant le schéma suivant, tu as gagné....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void MainLoop ( ...)
    {
       while ( 1 ) 
         {
            Get_Event(&event);
            Dispatch_Event(event);
         }
    }

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    92
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Côte d'Or (Bourgogne)

    Informations forums :
    Inscription : Mai 2005
    Messages : 92
    Points : 108
    Points
    108
    Par défaut
    Si la boucle est gérée par l'OS qui envoie un évènement à intervalles de temps régulier au callback d'affichage (timer), ça fait pas une boucle de moins qui tourne sur le système?

    Et pour le gestionnaire d'affichage, c'est pas plutot un switch sur les messages envoyés pas l'OS qu'un while, ce qui permet aussi d'avoir une boucle en moins qui tourne?

    Désolé, je suis pas expert.

  11. #11
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Biozic Voir le message
    Si la boucle est gérée par l'OS qui envoie un évènement à intervalles de temps régulier au callback d'affichage (timer), ça fait pas une boucle de moins qui tourne sur le système?

    Et pour le gestionnaire d'affichage, c'est pas plutot un switch sur les messages envoyés pas l'OS qu'un while, ce qui permet aussi d'avoir une boucle en moins qui tourne?

    Désolé, je suis pas expert.

    eh non !!!

    Simplement pour la bonne raison que pour faire le switch, il faut deja avoir l'evenement, donc son type...

    Dans un gestionnaire d'affichage, on se sait pas quand un evenement va se passer (cela depend de l'utilisateur). Il y a donc une boucle infinie pour recuperer les evenements....

    Il y a donc construction d'une queue d'evenements, exploration de cette queue, et dispatch a la bonne fenetre et/ou action...

    En general, dans les systemes evolues, c'est implemente dans un serveur (X par exemple).

    Quant au fonctionnement d'un shell, c'est la meme chose ....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    while ( 1 )
    {
       fprintf ( stdout, "\n%s",Prompt);
       fgets ( stdin, ....);
     
       switch ( ....)
      ....
    }

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    92
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Côte d'Or (Bourgogne)

    Informations forums :
    Inscription : Mai 2005
    Messages : 92
    Points : 108
    Points
    108
    Par défaut
    En fait on est d'accord : il n'y a pas de boucle infinie dans l'appli, seulement des callbacks, et la boucle infinie est dans l'OS. Donc rajouter une boucle infinie côté appli est redondant non? ou alors j'ai vraiement rien compris.

  13. #13
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    je voudrais pas etre... mais la je crois que t'as pas compris

    Dans l'OS, il y a plein de boucles infinies. J'en ai cite une, celle des shell, mais il y en a d'autres...

    Maintenant, un gestionnaire graphique est une appli, ou plus precisement la plupart du temps une bibliotheque a laquelle on se lie lors de l'edition de liens pour faire une appli...

    Dans cette bibliotheque (je ne connais pas assez VC++ pour le dire), mais en general pour les outils et les bibliotheques que je connais, dans le main, ou la MainWindow, une fois les fenetres creees et toutes les actions d'intiialisations faites, quand l'application demarre reellement, la derniere instruction du main est : MainLoop.

    Cette instruction est DANS la bibliotheque, et donc DANS l'appli, pas dans l'OS. Et cette instruction est un while infini...

    Si donc on veut faire une attente MAIS garder l'interface active, l'attente sera forcement declenchee par un des evenements traites dans cette MainLoop.. Donc le temps passe dans la Callback, le while de la MainLoop est bloque. Pour eviter qu'il ne reste bloque trop longtemps, on fait appel a une mini-fonction equivalente, quand on peut (dans mon exemple a chaque cycle), qui fait la meme chose (ou appelle directement le meme code que la MainLoop). On a dans ce cas un GUI toujours actif, avec un code s'executant "en parallele", ou assimile. On peut faire la meme chose lors d'un calcul tres long (par exemple du traitement d'image).

    On peut egalement se servir du meme mecanisme lors de programmation sockets ou autres, pour indiquer que la connection est toujours "live" pendant un traitement long...

    En fait, par rapport a ce que tu penses, qui appelle ta callback ??
    c'est la fonction de TON code, ce n'est pas l'OS. C'est juste que le Dispatch est cache pour toi par la bibliotheque et cette fameuse fonction MainLoop.

    Et rajouter une boucle infinie n'est pas redondant, puisque au moment ou ta callback a ete appelee, la boucle infinie de la MainLoop est bloquee en attendant le retour de ta callback.. Et donc tous les evenements survenant sont egalement bloques... Et c'est la maniere la plus sure de faire une attente (un sleep "gelera" l'application au niveau visuel, de meme que ne pas faire d'appel a l'Update si la callback (que ce soit en calcul ou en attente) est longue...)



  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    92
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Côte d'Or (Bourgogne)

    Informations forums :
    Inscription : Mai 2005
    Messages : 92
    Points : 108
    Points
    108
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    je voudrais pas etre... mais la je crois que t'as pas compris
    Héhé, pas de mal, c'est pas mon domaine de prédilection

    un gestionnaire graphique est une appli, ou plus precisement la plupart du temps une bibliotheque a laquelle on se lie lors de l'edition de liens pour faire une appli...
    Dans cette bibliotheque (je ne connais pas assez VC++ pour le dire), mais en general pour les outils et les bibliotheques que je connais, dans le main, ou la MainWindow, une fois les fenetres creees et toutes les actions d'intiialisations faites, quand l'application demarre reellement, la derniere instruction du main est : MainLoop.
    Cette instruction est DANS la bibliotheque, et donc DANS l'appli, pas dans l'OS. Et cette instruction est un while infini...
    ça j'avais pigé, j'avais juste placé la limite appli/OS à un autre endroit.

    Donc le temps passe dans la Callback, le while de la MainLoop est bloque. Pour eviter qu'il ne reste bloque trop longtemps, on fait appel a une mini-fonction equivalente, quand on peut (dans mon exemple a chaque cycle), qui fait la meme chose
    OK, c'est ça que j'avais zappé. Bon, finalement, je vais rester dans le camp des threads et des timers, c'est plus simple

    En tout cas merci pour les explications!

  15. #15
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    164
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 164
    Points : 161
    Points
    161
    Par défaut
    wow je ne pensais pas lancer un tel débat
    et je dois dire que le code et les termes utilisés pour l'explication de l'attente passive me déroute un peu vu que je n'ai pas encore ce niveau de connaissances.

    pour la fonction Sleep ça venait bien du S majuscule
    et comme vous l'aviez fait remarquer cela gèle tout le thread.
    Etant donné que je n'ai pas encore touché aux threads (ou très peu) je pense m'orienter vers une méthode utilisant les timers je vous tient au courant de l'avancement

    merci à tous

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-MAC 2011] Liste de validation avec paramètres dans une boucle de test
    Par cordy style dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 04/11/2014, 19h49
  2. Paramètre dans une boucle while
    Par fendry dans le forum Langage
    Réponses: 6
    Dernier message: 17/05/2014, 00h13
  3. sub avec paramétre dans une boucle
    Par gastoncs dans le forum VB.NET
    Réponses: 1
    Dernier message: 23/12/2011, 14h58
  4. Objet paramétré dans une boucle
    Par CedricMoi dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 05/02/2009, 10h21
  5. [bash]Modification de paramètres dans une boucle
    Par troumad dans le forum Shell et commandes GNU
    Réponses: 18
    Dernier message: 28/10/2007, 16h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo