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

Langage Delphi Discussion :

sleep avec une valeur inférieure à 1ms


Sujet :

Langage Delphi

  1. #1
    Membre averti Avatar de franckcl
    Homme Profil pro
    Developpeur Delphi
    Inscrit en
    Septembre 2004
    Messages
    516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Developpeur Delphi
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Septembre 2004
    Messages : 516
    Points : 443
    Points
    443
    Par défaut sleep avec une valeur inférieure à 1ms
    Bonjour,

    Dans la boucle "repeat ... until terminated" de mon thread je fais un sleep(1).
    Avec cette valeur le temps processeur de mon application est proche de zéro.
    Si je ne mets pas de sleep ou si je mets un sleep(0), le temps processeur passe entre 25 et 30, ce qui est trop !!

    Je cherche à accélérer la vitesse de mon thread, il me faudrait quelque chose comme sleep(0.1) mais cette fonction ne prend que des entiers.
    Existe-t-il une autre solution ?

    merci
    Franck

  2. #2
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    il y'a une solution possible ici:
    http://www.drbob42.com/uk-bug/hood-08.htm
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  3. #3
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 693
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 126
    Points
    13 126
    Par défaut
    Je ne vois pas pourquoi ce serait trop !

    Sleep(0) redonne la main tout en gardant le thread prêt à redémarrer s'il n'y en a aucun autre en attente. Tu ne peux pas faire plus rapide.
    Pourquoi vouloir ralentir une tâche si elle est la seule à bosser

    Sleep(1) met véritablement le thread en pause et c'est l'OS qui va décider quand il va redémarrer. Tu définis un temps d'attente minimum, mais il n'est pas garanti.

    Mais rien ne t'empêche de lancer un Sleep que toutes les 100 itérations

  4. #4
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    autre question que fait ce thread exactement, est il en train de faire du polling?
    Est-il en attente d'information d'autres thread?

    Dans le second cas un approche de type synchronisation par signaux est probablement préférable.
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  5. #5
    Membre averti Avatar de franckcl
    Homme Profil pro
    Developpeur Delphi
    Inscrit en
    Septembre 2004
    Messages
    516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Developpeur Delphi
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Septembre 2004
    Messages : 516
    Points : 443
    Points
    443
    Par défaut
    Oui c'est un thread qui fait du polling sur plusieurs ports de communication pour maintenir une base de données à jour.

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    C'est vrai que l'attente passive ce n'est pas terrible !

    Tu as besoin de faire un polling aussi intense ?
    Je fais aussi un outil de supervision, vu le nombre de périphérique que l'on gère, rien que le temps de tous les tester, je les fais un par un, selon les API ou la méthode de polling du périphérique :
    - certains sont asynchrones donc plusieurs polling simultané, la réponse arrivera par notification,
    - certains sont synchrones et répondent directement avec un délai plus ou moins long.

    Cela prend un certains temps !
    Dans mon programme, j'ai justement refait une partie de ça, pour créer un système de driver pour ainsi plus facilement changer d'API en fonction du fabricant\modèle de périphérique
    Tout le code est conçu pour gérer des "ping" asynchrones même si supporte les bloquants
    Avant cela utilisait directement les API de chaque marque à coup de if ou de swicthcase, maintenant tout passe par des interfaces\abstract class, l'implémentation étant déportée dans des DLL qui émulent le "ping" asynchrones pour tous
    Il y a donc des threads qui comme toi font une attente passive de la réponse si il n'y a pas un système de notification plus performant dans l'API utilisé
    Mais souvent c'est à coup de sleep(10), faut laisser le temps au matos de répondre surtout lorsqu'il se situe à plusieurs kilomètres relié par IP à travers un nombre important de routeurs ou un BUS RS422 (avec répétiteur)

    Le délai entre deux "séance de polling" est configurable mais cela peut dépasser la minute car le polling consomme de la bande passante (aussi bien sur le port USB, COM ou IP selon le périphérique ciblé) et comme en même temps, on doit dialoguer avec, si l'on est déjà en train de dialoguer avec c'est que l'on est connecté, donc inutile de poller

    D'ailleurs, je prévois de changer mon polling, si un périphérique est en cours d'utilisation, il ne le fera pas, la perte de connexion étant aussi gérée lors de son utilisation

    un Sleep(1) monte au pire à 1.995ms
    un Sleep(0) dépend du proc mais ça tourne vers 100ns à 2µs
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Membre averti Avatar de franckcl
    Homme Profil pro
    Developpeur Delphi
    Inscrit en
    Septembre 2004
    Messages
    516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Developpeur Delphi
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Septembre 2004
    Messages : 516
    Points : 443
    Points
    443
    Par défaut
    Mon superviseur est entièrement paramétrable et le nombre de tag à lire est donc très variable. Une attente de 1ms entre chaque tag peut effectivement être gênant lorsqu'il y en a beaucoup à scruter. Il est évident que je peux traiter plusieurs tag simultanément c'est d'ailleurs ce que je vais faire pour accélérer le processus. Mais à cette échelle de temps, une pause de 1ms est une éternité, c'est pourquoi je voulais savoir s'il existait une autre solution pour éviter de faire des "trains" de scrutation.

    Je me demandais aussi s'il était possible de créer un thread "temps réél" (quasi préemptif) ? quels sont le possibilités qu'offre Delphi à ce niveau (ou plutôt l'API) ?
    Je sais qu'il existe des solutions en visual c++, j'ai des exemples d''application qui font du polling sur IP toutes les 10ms dont rien ne peut perturber. J'ai pu le vérifier sur un analyseur (wireshark) pendant que je faisais tout un tas de manip sur le PC, transfert de fichier, accès réseaux etc...

    Impossible d'avoir ce résultat avec des threads "standards".

  8. #8
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 858
    Points : 11 299
    Points
    11 299
    Billets dans le blog
    6
    Par défaut
    Il doit être possible d'affecter un thread à un coeur d'un processeur multicore : regarde du côté de SetThreadAffinity, et - bien sûr - de régler sa "Priority"
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  9. #9
    Membre confirmé
    Homme Profil pro
    Santé
    Inscrit en
    Septembre 2010
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Santé
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2010
    Messages : 290
    Points : 534
    Points
    534
    Par défaut
    Citation Envoyé par franckcl Voir le message
    Je me demandais aussi s'il était possible de créer un thread "temps réél" (quasi préemptif) ? quels sont le possibilités qu'offre Delphi à ce niveau (ou plutôt l'API) ?
    Les Fibers ?

    Using Fibers



    PS : Attention à Sleep(0) !
    Sleep(0) rend la main pour un thread prêt à être executer et de même priorité.
    VOIR cet article.

  10. #10
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Ah !
    c'est un sleep entre chaque polling et non durant une attente de réponse !
    Je fais un gros train, si j'ai 100 périphériques à "pinguer", je le fais d'un seul coup, un train puis pendant n minutes cela attend puis ça relance un train !
    Cela ne pose aucun problème !

    En Prod, bcp de client sont à 5 voire 10 minutes entre chaque train
    Le Défaut dialogue pouvant être détecté par d'autres moyens (là le code concerne une caméra, donc si le programme est en train de l'enregistrer ou un autre programme la visualise, il y a une détection de perte de connexion, perte de flux ...)
    Si tu passes ton temps à "pinguer", tu vas finir par dégrader les perfs du "périphérique" surveillé ! C'est un peu con non ?

    Par exemple, j'ai des DVR qui ne supporte pas plus de 10 simultanés (petit prix petite perf), si j'ai 4 caméras en enregistrement en cours (depuis le serveur, ça me consomme une connexion), que ces même 4 caméras sont visualisés sur un moniteur vidéo sur plusieurs ordi, ça me bouffe autant de connexion que d'ordi, je peux finir par arriver à 10, du coup, le polling, si je lance va être en erreur car plus de connexion dispo alors que le périphérique fonctionne !

    Pour mes tests, en mettant -10 ça comprend 10 secondes, ça m'évite d'attendre comme un glandu durant une minute entre chaque "train" de polling

    Moi, je ne fais aucune attente en deux polling au sein d'un même train, voici mon code élagué
    Un Thread lancé depuis le début de l'appli (un serveur DCOM)
    Ce thread pouvant être terminé et relancé au besoin (fin de l'appli, changement de donnée ou conf...)

    L'ancien programmeur lui avait utilisé un TTimer

    Code c++ : 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
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    //---------------------------------------------------------------------------
    void __fastcall TxxxCameraPollThread::Execute(void)
    {
      try
      {
        while ( ! Terminated)
        {
          if (WaitForNextPoll())
          {
            xxxFormatOutputDebugString("[Info] - Session de Polling - %d Caméras", (FRegisteredCameraList.size()));
     
            for (TxxxCameraPollTools::TCameraDeviceNumberList::const_iterator it = FRegisteredCameraList.begin(); it != FRegisteredCameraList.end(); ++it)
            {
              if ( ! Terminated)
              {
                try
                {
                  TxxxCamera *ObjCam = TxxxCameraManager::ProviderManager()->FindByDeviceNumber(*it);
                  if (ObjCam)
                  {
                    if (ObjCam->IncrementReference())
                    {
                      try
                      {
                        if ( ! Terminated)
                        {
                          TxxxCameraTestConnectionState TestConnectionState = ObjCam->TestConnectionState;
     
                          // Un Test est en attente de démarrage ou est toujours en cours !
                          // On considère que c'est un défaut, de toute façon on relance un autre test !
                          if ( ! Terminated && ((TestConnectionState == sctcsWaiting) || (TestConnectionState == sctcsRunning)))
                          {
                            ObjCam->TestConnectionTimedOut();
                            if (FOnNoPolling)
                              FOnNoPolling(ObjCam);
                          }
     
                          // TestConnection peut être bloquant ou pas, cela dépend l'implémentation
                          if ( ! Terminated)
                          {
                            TestConnectionState = ObjCam->TestConnection();
     
                            // La Demande de Test n'a pas pu être faite, je considère cela comme un Défaut !
                            if ( ! Terminated && ((TestConnectionState == sctcsNone) || (TestConnectionState == sctcsUnreachable)))
                              if (FOnNoPolling)
                                FOnNoPolling(ObjCam);
                          }
                        }
                      }
                      __finally
                      {
                        ObjCam->ReleaseReference();
                      }
                    }
                  }
                }
                catch(const Exception &e)
                {
                  xxxOutputExceptionString("[Error] %0:s::Execute : %2:s [%1:s]", this, e);
                }
              }
              else
                break;
            }
          }
        }
      }
      catch(Exception *e)
      {
        FExceptionClass = e->ClassType();
        FExceptionMessage = e->Message;
        if (FOnException)
          FOnException(this);
      }
     
      if (FOnFinish)
        FOnFinish(this);
    }
     
    //---------------------------------------------------------------------------
    bool TxxxCameraPollThread::WaitForNextPoll()
    {
      // Le Premier Démarrage est au bout de 5 secondes !
      // Les Suivants seront en fonction du Délai
      if (FNextPollingTime.Val <= 0)
        FNextPollingTime = IncSecond(Now(), 5);
      else
        // Positif, c'est le vrai Polling, en Minute
        // Négatf, c'est le débogage du Polling, en Seconde !
        if (FPollingDelayMinute > 0)
          FNextPollingTime = IncMinute(Now(), FPollingDelayMinute);
        else
          FNextPollingTime = IncSecond(Now(), -FPollingDelayMinute);
     
      // On attend tant que le Délai n'est pas écoulé
      // On vérifie régulièrement que l'on a pas demandé l'abandon du Polling !
      while ( ! Terminated && (FNextPollingTime >= Now()))
        Sleep(10);
     
      return ! Terminated;
    }
    Code c++ : 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
    //---------------------------------------------------------------------------
    TxxxCameraTestConnectionState TxxxCameraCustom::TestConnection()
    {
      FTestConnectionState = sctcsNone;
      try
      {
        if (IsValidDevice())
        {
          FTestConnectionState = sctcsCalling;
          SetTestConnectionStateFromHardwareCameraState(CameraPurposeInterface->TestConnection(), false);
        }
      }
      catch (const ExxxHardwarePurposeError &e)
      {
        FTestConnectionState = sctcsUnreachable;
     
        xxxOutputExceptionString("[Warning] %0:s : %2:s [%1:s] !", this, e);
      }
     
      return FTestConnectionState;
    }

    l'implémentation de CameraPurposeInterface étant dans différentes DLL, les comportements sont très variés !

    L'obention des autres état comme sctcsSuccess, sctcsFailure, sctcsWarningNoVideo, sctcsWarningNoStream ...
    sont obtenus via un TxxxCameraPollingEvent parfois quelques secondes après le TestConnection() et pas forcément dans l'ordre d'ailleurs puisque dépend des timeout, souvent un défaut arrive tardivement par rapport à une connexion OK

    A mon avis c'est la dessus que tu dois travailler !
    Faire en sorte que ton "polling" puisse lancer une série de test de façon asynchrone !
    Tant qu'il y en a un en cours, tu attends qu'il soit fini (ou tu le saborde pour en lancer un autre)
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  11. #11
    Membre averti Avatar de franckcl
    Homme Profil pro
    Developpeur Delphi
    Inscrit en
    Septembre 2004
    Messages
    516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Developpeur Delphi
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Septembre 2004
    Messages : 516
    Points : 443
    Points
    443
    Par défaut
    Merci à tous pour ces renseignements très utiles !!
    Je vais voir ce que je peux faire avec tous ça.

  12. #12
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2005
    Messages : 100
    Points : 118
    Points
    118
    Par défaut
    bonjour,

    Et si vous utilisez à la place de sleep une boucle d'attente avec un maximum réglable à volonté :

    Ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    i:=1;
    while i<10000 do
     i:=i+1;
    end;
    il suffit d'augmenter ou diminuer 10000 en fonction de votre besoin (augmenter pour plus de temps)
    A+

  13. #13
    Membre averti Avatar de franckcl
    Homme Profil pro
    Developpeur Delphi
    Inscrit en
    Septembre 2004
    Messages
    516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Developpeur Delphi
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Septembre 2004
    Messages : 516
    Points : 443
    Points
    443
    Par défaut
    Camatchou
    si je fais une boucle while alors je consomme inutilement du temps processeur et ce n'est pas ce que je cherche. Je cherche au contraire une solution qui optimise le processeur.
    L'avantage du sleep c'est que le temps processeur est alloue aux autres taches. on peut facilement le vérifier dans le gestionnaire de taches : avec le sleep, le temps processeur occupé par l'application tourne autour de zéro alors que sans le sleep on passe à 30 et si on rajoute d'autres thread comme ça alors ça va être la cata.

Discussions similaires

  1. Réponses: 2
    Dernier message: 01/07/2014, 17h14
  2. problème avec une valeur decimal
    Par vbcasimir dans le forum Langage
    Réponses: 2
    Dernier message: 11/10/2005, 13h52
  3. Problème avec une valeur decimale
    Par vbcasimir dans le forum Linux
    Réponses: 3
    Dernier message: 12/07/2005, 11h00
  4. avoir un champ avec une valeur numerique qui se decremente
    Par romeo9423 dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 15/02/2005, 14h29
  5. champ avec une valeur?
    Par sonialem2000 dans le forum Bases de données
    Réponses: 2
    Dernier message: 22/06/2004, 08h23

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