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 :

Faire attendre un temps sans Sleep()


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 26
    Par défaut Faire attendre un temps sans Sleep()
    Bonjour,
    Je programme une application qui dialogue avec le port serie.
    Mon probleme est que je dois récupéré une donnée par le port serie en reponse a celle que j'ai envoyé...

    J'envoi une trame ":RDD00500" et la je dois attendre environ une seconde avant de pouvoir récupérer la donnée...

    J'ai essayé de faire patienter avec Sleep() mais il me bloque l'application et par conséquent je n'arrive pas a récupéré la donnée

    Mon code :
    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
     
    void Test_EPROM(void)
                    {
                    Adresse="";
                    Application->ProcessMessages();// sencer ne pas bloquer l'application
                    ComPort1->ClearBuffer(true, true);
                    Sleep(100);
                    ComPort1->WriteStr(":RDD00500");
                    Sleep(1000);
                    if(Adresse=="3117")
                             ListBox_Recap->Items->Add("EPROM OK");
                    else
                             ListBox_Recap->Items->Add("EPROM KO");
     
     
                    }
    Derriere cela j'ai un timer qui interroge tout les 50ms le buffer pour récuper les données

    Code de mon timer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    AnsiString Buffer;
            ComPort1->ReadStr(Buffer, ComPort1->InputCount());
            if(Buffer!="")
                    {
                     Adresse=Buffer.SubString(4,4);
                     Octet=Buffer.SubString(8,2);
                    }
    Si quelqu'un peut m'aider a résoudre mon probleme...
    Merci d'avance

    Ps: Je boss sous C++ Builder 6 Pro

  2. #2
    Membre éclairé Avatar de ZaaN
    Inscrit en
    Novembre 2005
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 819
    Par défaut
    deux solutions:
    créer un thread qui fait uniquement de l'ecoute (bloquant)
    ou
    utilise des fonctions de communication asynchrone

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 26
    Par défaut
    Merci pour ta réponse mais je suis un peu perdu..

    Je ne vois vraiment pas comment faire avec un thread ( Je débute en C++)

    et encore moins avec des fonctions de communication asynchrone..

  4. #4
    Membre éclairé Avatar de ZaaN
    Inscrit en
    Novembre 2005
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 819
    Par défaut
    1)
    2) MSDN
    3)

    et si t'as encore des questions, pose les moi

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 26
    Par défaut
    Je me suis permis de poster un message sur le forum.. car je n'avais pas trouvé réponse ailleur...
    La FAQ ne me renseigne pas plus puisque je ne sais comment faire...

    Enfin si quelqu'un passe par la et a le courage de m'expliquer... merci a lui

  6. #6
    Membre éclairé Avatar de ZaaN
    Inscrit en
    Novembre 2005
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 819
    Par défaut
    si tu bosses avec Windows, penche toi vers l'API Win32.
    chapitre Process & thread. Ou les Winsock si tu veux la version avec fonction asynchrone

    Il existe surement des bibliothèque avec Borland, mais je les connais pas.

    Si tu bosses avec unix/linux je crois qu il faut te diriger vers POSIX mais je suis pas sur du tout...

  7. #7
    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
    Par défaut
    Le plus simple pour lancer les threads, quelle que soit la plate-forme, c'est boost::thread. Par contre, le plus dur n'est pas de lancer un thread, c'est de bien organiser les communications entre thread, mais par contre, désolé, je ne me sens pas d'expliquer ça dans un forum.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 26
    Par défaut
    Merci je vais regarder sur les liens

    Au pire je verrais avec mon prof..

  9. #9
    Membre émérite
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Billets dans le blog
    1
    Par défaut
    Bjr,

    Ca fait un petit moment que j'ai programmé du multithread et c'était aps sous Borland mas Microsoft. Donc l'aide que je peux t'apporter risque d'être limitée.

    Tout d'abord je te conseille vivement de faire du multithread.
    Un thread pour le matériel,
    un autre pour l'interface utilisateur
    un troisième pour les calculs si il y a du gros travail à faire.

    Les threads de calcul sont simples dans la mesure ou ils se lancent quand il y a un travail à faire, s'exécutent à leur rythme, et se terminent par eux même quand ils ont livré les résultats.

    Ce qui t'interesse, c'est les threads liés au hardware.
    Lancer un thread (en VC)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    acquisition_thread = AfxBeginThread(acquisition, LPVOID(&data.front()), THREAD_PRIORITY_ABOVE_NORMAL) ;
    Comme tu vois c'est pas standard comme appel. mais c'est pas sorcier non plus.

    Activer-endormir un thread : Ca se fait avec des portes. En VC on crée ces portes par CreateEvent. Une porte peut être normalement ouverte, normalement fermée, ou double. Sur une porte, on peut la basculer, l'ouvri, la fermer, ou envoyer un pulse. Les portes sont créées par le thread racine.

    Dans le thread fils, il y a des instructions qui sont bloquantes : le thread attend derrière ces instructions jusqu'à ce qui se passe ce que t'as demandé, Sauf qu'il ne consomme pas de CPU pendant l'attente.

    Voila un exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    // flat sleep that can be interrupted by end-of-thread request
    bool CMotor::WSleep(unsigned milliseconds) {
    	DWORD r = WaitForSingleObject(g_hClose[k_ThreadID_Motor], milliseconds) ;
    	if (r == WAIT_TIMEOUT) return WaitDone ; // wait has timed out at the required moment
    	else return PleaseTerminate ; // wait has exited prematurously because of end of thread request
    }
    PS: Si tu regardes bien le code ci-dessus, j'ai toujours 2 possibilités d'ouvrir mes portes car quand je veux terminer le programme, il fqut que j'ai un "passe-partout" pour ouvrir toutes les portes et permettre à tous les threads de reconnaitre une demande de terminaison et de sortir normalement.

    Dans la configuration des portes, il y a toujours une option de timeout. C'est probablement ça qui te faut. Tu jettes ton thread derière une porte fermée qui ne s'ouvre jamais, mais tu mets un timeout de la durée nécessaire à ton attente.

    Dernière remarque sur la gestion du temps sous Windows. Windows n'est pas un système temps réel. cela veut dire que tu n'as pas la maitrise du temps sous windows. L'OS te donne la main quand il veut et pour la durée qu'il veut. Par exemple, je me suis arraché les cheveux pour faire une mesure précisément tous les 5 millisecondes et je n'y suis jamais arrivé. Pour connaître la fréquence effective de mes mesures ... eh bien je compte combien j'ai de données et je divise par le temps total !!!! la pire des solutions pour comprendre que tu n'as pas la maîtrise du temps, c'est le timer. les timers sont fait pour rafraîchir des progress-bars, pas pour piloter du hardware.

    Les timers sont gérés par ton programme lui-même (qui peut être occupé à autre chose). Les portes derrières lesquelles attendent les threads sont gérées par l'OS via l'API. C'est quand même plus fiable et plus précis.

    Maitenant, si c'est juste pour faire de la communcation série, tu dois avoir des codes tout prêts sur Internet faut pas te faire ### avec du multitthread pour ça.

    OL

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 26
    Par défaut
    Merci ol9245 pour ta réponse trés complete

    Je vais regarder sur le net si je ne trouve pas un bout de programme déja tout fait alors...

    ca m'évitera sans doute beaucoup d'ennui je pense

    Mais je vais quand meme essayer en parallele avec les threads !

    Encore Merci


    Edit : Tu avais raison il existe bien quelque chose pour m'aider

    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
    ComPort1->Events = TComEvents(); // Effacer tous les évenements
        ComPort1->Connected = true;
     
        TComEvents Ev;
        Ev << evRxChar;
        ComPort1->WaitForEvent (Ev, 0, 5000);
        // Attend un événement OnRxChar ou 5 secondes avant de continuer
     
            if (Ev.Contains(evRxChar))
            { 
                // Executer une action, une donnée est arrivée             
            }
            else 
            { 
                // Executer autre action, les 5 secondes se sont écoulées             
            }
    PROBLEME RESOLU :p

  11. #11
    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
    Par défaut
    Citation Envoyé par ol9245
    Dernière remarque sur la gestion du temps sous Windows. Windows n'est pas un système temps réel. cela veut dire que tu n'as pas la maitrise du temps sous windows.
    Il n'est effectivement pas temps réel, et si tu as besoin de toujours répondre au moment voulu, il te faut te tourner vers un OS temps réel (si le reste de ton appli est lié à windows, il y a RTX qui offre une voie de transition).

    Maintenant, si tu acceptes de tenir le timing avec un certaine probalité d'erreur, l'expérience m'a prouvé que pour un timing de 50ms, windows est en général très suffisant.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  12. #12
    Membre émérite
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par JolyLoic
    pour un timing de 50ms, windows est en général très suffisant.
    Je confirme : 50 ms c'est très jouable.
    Pour 5 ms, avec des prouesses logicielles et un CPU mort d'épuisement (sisi, j'ai dit au mec de DELL ce que je faisais et il m'a demandé de pas le refaire sur le nouveau CPU qu'il m'a mis grâce à la garantie), on peut limiter à 5% le nombre d'événements ratés.
    Pour 1ms : pas la peine d'essayer.

    OL

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

Discussions similaires

  1. Faire une recherche avec/sans accents
    Par Wedge3D dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 21/02/2007, 10h43
  2. faire attendre un programme qu'un événement se déclenche
    Par fabrisss dans le forum API standards et tierces
    Réponses: 20
    Dernier message: 21/10/2005, 15h34
  3. Faire un Select v1 sans mettre v1 dans Group By
    Par faayy dans le forum Langage SQL
    Réponses: 6
    Dernier message: 12/05/2005, 09h28
  4. Réponses: 19
    Dernier message: 28/01/2005, 09h52
  5. [NASM] Faire un prog.exe sans prog.obj, pourquoi ?
    Par madax dans le forum Assembleur
    Réponses: 1
    Dernier message: 07/01/2005, 01h23

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