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 :

Comment faire un usleep inférieur à 100000 micro secondes


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Novembre 2016
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Novembre 2016
    Messages : 11
    Points : 9
    Points
    9
    Par défaut Comment faire un usleep inférieur à 100000 micro secondes
    Bonjour et merci d'avance pour votre aide.

    Je veux faire une pause de l'ordre de la milliseconde. Cependant, le niveau de précision atteind n'est pas bon dès que usleep est inférieur à 100000. Ne peut on pas faire un usleep(100); ?

    Precision correct :
    Quand je place boucle=50 et pause=100000, alors j'obtiens bien 5 secondes de pause pour usleep et idem pour nanosleep

    Précision incorrect :
    Quand je place boucle=500 et pause=10000, alors j'obtiens 10 secondes de pause pour usleep et 9 secondes pour nanosleep
    Quand je place boucle=5000 et pause=1000, alors j'obtiens 28 secondes de pause pour usleep et 20 secondes pour nanosleep


    Voici mon code de test :

    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
     
    	time_t t0;
    	struct tm * t0_structure;
    	unsigned long i;
    	unsigned long pause,boucle;
    	struct timespec req;
     
    boucle=500;	
    pause=10000;
     
    	req.tv_sec=0;
    	req.tv_nsec=1*1000*pause;
     
    	t0=time(0);
    	for (i=0;i<boucle;i++)
    		usleep(1*pause);
    	t0=time(0)-t0;
    	t0_structure=gmtime(&t0);
    	printf("\nTemps d'execution usleep : %d:%d:%d\n",t0_structure->tm_hour,t0_structure->tm_min,t0_structure->tm_sec);
     
    	t0=time(0);
    	for (i=0;i<boucle;i++)
    		nanosleep(&req,NULL);
    	t0=time(0)-t0;
    	t0_structure=gmtime(&t0);
    	printf("\nTemps d'execution nanosleep : %d:%d:%d\n",t0_structure->tm_hour,t0_structure->tm_min,t0_structure->tm_sec);
    Christophe

  2. #2
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    La solution est précisément d'utiliser nanosleep, qui offre une résolution égale ou meilleure à usleep comme précisé dans les pages de manuel correspondantes.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Novembre 2016
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Novembre 2016
    Messages : 11
    Points : 9
    Points
    9
    Par défaut
    Oui, mais dans mon code, je test usleep et nanosleep. Et les deux manque de précision et sont trop lent.

  4. #4
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Par rapport à quoi ? Les deux ne font rien de plus que leur part des contrats décrits dans leurs man respectifs.

    Il est évident que plus la durée de « sommeil » requis est courte, moins l'impact des paramètres extérieurs (résolution d'horloge native, changements de contexte, interruptions, préemption par les autres processus..) est négligeable sur le résultat final.

    Si ça ne suffit pas à ton cas d'utilisation (je repose la question : quel est-il ?), il va falloir taper dans la documentation du processeur voire investir dans du matériel dédié.

  5. #5
    Membre éprouvé
    Avatar de Garvelienn
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2016
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Septembre 2016
    Messages : 244
    Points : 993
    Points
    993
    Par défaut
    Je vais peut-être répondre à côté mais que donne la std ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::this_thread::sleep_for(std::chrono::microseconds(1));
    «Le management, tel qu’on l’apprend dans les écoles et tel qu’on l’applique ensuite, sous prétexte de «motivation du personnel», organise exactement le contraire, à savoir la démotivation organisée.» - Bernard Stiegler

  6. #6
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Nous sommes en C.

  7. #7
    Membre éprouvé
    Avatar de Garvelienn
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2016
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Septembre 2016
    Messages : 244
    Points : 993
    Points
    993
    Par défaut

    Pardonnez-moi
    «Le management, tel qu’on l’apprend dans les écoles et tel qu’on l’applique ensuite, sous prétexte de «motivation du personnel», organise exactement le contraire, à savoir la démotivation organisée.» - Bernard Stiegler

  8. #8
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Il y a aussi que les systèmes sont incapables d'une précision absolue (cela dit, pour une milliseconde, ca devrait passer).
    Mais as-tu besoin d'une pause réellement précise?
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  9. #9
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Points : 28 119
    Points
    28 119
    Par défaut
    Bonjour,

    Un peu d'informations sur le sujet :
    Lorsqu'un processus est prêt, il est mis dans une file d'ordonnancement du processeur. Lorsque c'est son tour, ton processus se voit allouer un quantum de temps processeur, de l'ordre généralement de quelques millisecondes (très fortement dépendant du système). Une fois qu'il a épuisé son temps, ou bien s'il n'est plus prêt (par exemple suite à une demande d'ouverture d'un fichier sur disque), il est remis en file d'attente.

    S'il n'a pas consommé tout son quantum de temps, il se voit attribuer une priorité un peu plus élevée, mais JAMAIS une priorité absolue car sinon on pourrait arriver à un phénomène de famine (c'est à dire que certains processus ne se verraient plus attribuer de temps sur le processeur).

    Donc dans le meilleur des cas, tu vas avoir le comportement suivant :
    P1 est ton processus, P2 est le seul autre processus.
    P1 arrive sur le processeur, fait un truc, et demande à s'endormir 1ms --> il est donc mis en file
    P2 arrive sur le processeur, et se voit attribuer un quantum de temps. Ce quantum est bien évidemment supérieur à 1ms, donc hop, tu as déjà dépassé le temps d'endormissement voulu pour P1.


    Néanmoins, il existe des solutions à étudier pour ton cas :
    1/ Changer la priorité : cela nécessite des droits spécifiques lors du démarrage, mais permet à ton processus d'être vraiment prioritaire. Attention néanmoins, ça ne te permettra jamais de descendre à la milliseconde.
    2/ Rendre ton processus temps-réel. On parle ici de temps réel OS, donc du faux temps réel. Néanmoins, cela comporte des risques, car si ton processus demande toutes les ressources de la machine, il les obtiendra, rendant la machine inutilisable (reset hardware obligatoire).
    3/ Utiliser une carte FPGA pour implémenter ton processus : c'est la seule solution qui te permettra d'obtenir réellement une telle précision. Mais cela demande quelques efforts en plus du temps de programmation.


    Enfin, je serai curieux de savoir pourquoi tu as besoin d'une telle précision ?
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  10. #10
    Membre expérimenté

    Homme Profil pro
    Responsable des études
    Inscrit en
    Mars 2009
    Messages
    553
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2009
    Messages : 553
    Points : 1 672
    Points
    1 672
    Par défaut
    Hello,

    J'en rajoute une couche par rapport aux réponses précédentes. Consulte la documentation de ces fonctions, c'est probablement écrit en toute lettre: la seule garantie que tu as, c'est d'obtenir un temps de sommeil au moins égal au délai passé en paramètre. Cela veut dire que ce ne sera jamais moins, mais que cela peut être plus.

    Donc, faire 10 appels à "sleep(N)" donnera généralement un temps plus long qu'un seul appel à "sleep(10*N)".

  11. #11
    Futur Membre du Club
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Novembre 2016
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Novembre 2016
    Messages : 11
    Points : 9
    Points
    9
    Par défaut
    Merci pour toutes vos réponses qui me permette de progresser.

    Vous avez raison, après lecture de vos commentaire sur les fonctions usleep et nanosleep, je n'ai pas besoin d'une précision en fait, j'ai juste besoin de ralentir mon code.

    J'ai une boucle qui tourne et qui effectue son traitement. Lorseque je l'execute sans ralentissement, j'otient une vitesse de traitement de 30 000 send par seconde. l'impact étant le réseau WAN qui sature et j'aimerais donc pouvoir réguler le débit. Pour ça, je met un usleep(100000), mais là ça ralentit de trop et si je mete une valeur plus petite dans usleep, on en revient à la question première où usleep ne descend pas à ce niveau.

    Donc deux idées me vienne, peux etre pourrais-je faire un usleep non pas à chaque boucle, mais tous les 1000 boucle.
    J'ai essayé aussi de remplacer par une boucle :
    f;
    Cette seconde idée est très flexible, car je mete la valeur de x comme je veux et je peux ainsi réguluer de manière minutieuse mon flux réseau génré. Cependant, en appliquant cette méthode, l'occupation CPU passe à 100%.

    Quand pensez-vous ?

  12. #12
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 372
    Points : 23 628
    Points
    23 628
    Par défaut
    Bonjour,

    Citation Envoyé par alexandre.dufoure Voir le message
    Cette seconde idée est très flexible, car je mete la valeur de x comme je veux et je peux ainsi réguluer de manière minutieuse mon flux réseau génré. Cependant, en appliquant cette méthode, l'occupation CPU passe à 100%.

    Qu'en pensez-vous ?
    Que cela s'appelle une « attente active » et que c'est considéré comme une mauvaise pratique, voire un piège dans lequel il est tentant de tomber mais qu'il faut pourtant éviter. C'est à proscrire si ton but est simplement de faire une petite pause (sleep() et usleep() servent à ça).

    Cela pourrait sembler être une bonne idée s'il s'agissait de faire une temporisation de précision mais malheureusement, outre le fait que ce serait coûteux à terme pour tout le reste du système, tu ne pourras plus jamais, de nos jours, garantir de façon exacte la durée de ta boucle, et ce pour trois raisons : d'abord parce que les différentes machines sur lesquelles ton programme va fonctionner vont toutes êtres cadencées à des fréquences différentes sans compter le fait que sur une même machine, cette fréquence peut être volontairement dégradée pour économiser l'énergie ou au contraire accélérée en cas de pic d'activité. Ensuite le micro-processeur va faire beaucoup d'optimisations (pipeline, prédictions de branchement, etc.) qui vont influer sur la durée de ta boucle. Enfin, et surtout, ton programme va fonctionner au sein d'un environnement géré par un OS et sera soumis aux interruptions matérielles (IRQ) et à la préemption du noyau. Donc ta boucle va être sans arrêt interrompue pour traiter les événements systèmes ou matériels en attente (frappe clavier, déplacement souris, arrivée de trafic sur la carte réseau…).

    Note toutefois que cela se faisait dans les années 1980 et 1990 quand, d'une part, un modèle de machine déclaré était garanti d'être le même chez tout le monde et que les programmes en assembleur étaient encore légion. Comme pratiquement aucun OS grand public de l'époque n'était multitâche et que les microprocesseurs eux-mêmes étaient relativement lents (mais autrement plus facile à assimiler qu'un Intel de dernière génération), il était courant de faire des programmes qui se permettaient de désactiver temporairement les interruptions et qui comptaient le nombre de cycles machines consommés par chaque instruction. On obtenait alors une précision correspondant à celle du quartz qui cadençait le micro-processeur. C'était, entre autres, nécessaire pour exploiter le lecteur de disquettes dont le contrôleur était très rudimentaire, et c'est pour cela que les systèmes d'exploitation semblent toujours très « accaparés » quand on en fait fonctionner un.

    Par contre, en ce qui te concerne (et pour avoir lu quelques uns de tes autres messages), il ne faut pas aborder la programmation de la même façon qu'on étudie les mathématiques, c'est-à-dire considérer les fonctions comme des identités absolues, peu importe la manière dont on en détermine la valeur a posteriori mais, au contraire, considérer que ta machine est un ensemble fini et limité de ressources. Il t'appartient donc de les économiser, de les utiliser que lorsque c'est nécessaire et de les libérer après usage. Allouer 24 giga-octets pour gérer un cube de 1024 éléments par côté, par exemple, n'est pas une bonne approche. C'est un peu comme vouloir ouvrir un PDF de 1000 pages en ouvrant directement mille fenêtres contenant chacune une page. L'ouvrir ligne à ligne n'est pas pratique non plus, mais la meilleure approche consiste bien à ouvrir une fenêtre d'une seule page que l'on puisse voir dans son ensemble, puis passer de l'une à l'autre.

    Pour le problème qui t'intéresse dans ce fil, il faut d'abord étudier le problème en amont : ta volonté in fine n'est pas de faire une temporisation en soi, mais d'éviter un engorgement réseau. Généralement, il est plus intéressant de voir si tu peux expliquer cela au système d'abord plutôt que mettre en place un artifice pour y parvenir car cela laisse plus de latitude à ce dernier pour gérer les ressources comme il l'entend, et cela simplifie considérablement ton programme. Il existe notamment la commande tc pour mettre en forme le trafic réseau. Après, faire 30000 send par seconde accapare beaucoup de ressources système également. Il est préférable de déclarer un buffer dans ton programme et n'émettre son contenu que lorsqu'il est plein.

    Pour les temporisations, enfin : sleep() et usleep() suffisent pour la majorité des cas. nanosleep() a l'avantage d'être plus précis dans la description de sa demande, mais rien ne garantit que la machine soit techniquement capable d'honorer une telle requête à la nanoseconde près. Et surtout, tous ces appels (comme tous les autres appels système) peuvent être interrompus par un signal et rendre la main avant terme (cas qu'il faut gérer). Voir également man time.

    Il existe également alarm() qui te permet de demander à être prévenu, par la réception d'un signal, de l'échéance d'un timer armé au moment ou tu appelles cette primitive. Tu peux exploiter le paramètre timeout des appels select() et poll() si tu es en attente d'événements extérieurs pendant cette période.

    Certains périphériques (comme des cartes réseau) proposent au niveau matériel une interruption « Almost Ready » permettant de prévenir la machine de la fin imminente d'un processus, de façon à suivre l'échéance en attente active de façon à être très précis sans accaparer inutilement trop de ressources, mais cela va surtout concerner les développeurs de pilotes de périphériques.

    En descendant, le noyau tient en permanence à jour une variable appellée jiffies qui compte le nombre de « tops d'horloges » (formellement, incrémenté à chaque fois que le timer matériel de la machine déclenche une interruption). La lire est extrêmement rapide, mais elle n'est accessible directement qu'en mode noyau. Il faut passer par un appel système pour le faire depuis l'user space.

    Si ce n'est toujours pas assez précis, tu peux te rabattre sur la solution en assembleur exposée ci-dessus. Tu peux aussi faire une boucle exploitant l'instruction RDTSC (Read Timestamp Counter) disponibles sur tous les x86 depuis le Pentium. Le microprocesseur tient le compte du nombre de cycles écoulés depuis le dernier reset et totalement indépendamment des logiciels qu'il exécute. Un tour de boucle ne se fera pas en moins d'une dizaine de cycle, cependant, et la durée d'un cycle dépendra de la machine sur laquelle ils sont comptés. Donc il faudra calibrer ta boucle au préalable.

    Enfin, tu peux utiliser un timer externe dédié à cette tâche, qui te préviendra légèrement à l'avance et te donnera le top à l'échéance. Si c'est encore trop imprécis, alors la solution ultime consiste effectivement à recourir au FPGA comme expliqué ci-dessus.

  13. #13
    Membre expérimenté

    Homme Profil pro
    Responsable des études
    Inscrit en
    Mars 2009
    Messages
    553
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2009
    Messages : 553
    Points : 1 672
    Points
    1 672
    Par défaut
    Hello,

    La discussion suivante sur stackoverflow pourrait te donner des pistes:
    http://stackoverflow.com/questions/2...onnection-in-c

  14. #14
    Futur Membre du Club
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Novembre 2016
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Novembre 2016
    Messages : 11
    Points : 9
    Points
    9
    Par défaut
    Merci encore une fois à tous pour votre aide.

    La maitrisse du flux par la gestion de la file d'attente de la carte réseau ne peux pas fonctionner dans mon cas, car ce n'est pas mon serveur, ni ma carte qui sature, c'est le routeur qui se trouve derriere. Donc en fait, le buffer de ma carte réseau est vide et la congetion se produit sur un autre équipement. Mais merci de l'info, je garde l'idée pour d'autre dev

    Sinon, j'ai compris que les pause n'étaient pas fixe, mais minimum. Et que déscendre à 0.01s et voir moins était à proscrire.
    Je vais positionner un sleep de 0,1s toute les N trame. Ainsi, je garde la stabilité et la garantie de la pause et la flexibilité de la durée par le choix du nombre de trame.

    J'essai, et je vous dirais si cela à des impacts non prévu.

    Christophe.

    P.S. Obsidian
    Merci pour ce long message que je dois relire plusieurs fois et qui m'apporte plusieurs réflexions. Ce sont que des infos et remarques intérressantes.

  15. #15
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 372
    Points : 23 628
    Points
    23 628
    Par défaut
    Bonjour,

    Citation Envoyé par alexandre.dufoure Voir le message
    Merci encore une fois à tous pour votre aide.

    La maitrisse du flux par la gestion de la file d'attente de la carte réseau ne peux pas fonctionner dans mon cas, car ce n'est pas mon serveur, ni ma carte qui sature, c'est le routeur qui se trouve derriere. Donc en fait, le buffer de ma carte réseau est vide et la congetion se produit sur un autre équipement. Mais merci de l'info, je garde l'idée pour d'autre dev
    Oui, mais justement : ça veut dire que ton vrai problème est celui-ci. Ce qu'il faut, donc, c'est utiliser un protocole qui soit capable de gérer tout cela de bout en bout, et laisser le système s'occuper de cela au mieux, de manière à ce que cela soit transparent pour ton programme. Non seulement, ça simplifie considérablement les choses, mais cela laisse toute latitude à l'administrateur de ton réseau (toi ou n'importe quelle autre personne) pour le gérer comme il l'entend, en accordant plus ou moins de trafic en fonction des besoins.

    Normalement, le TCP/IP est fait pour cela. C'est un protocole bidirectionnel qui fonctionne par accusés de réception successifs se référant chaque fois au précédent bloc. Donc, si l'équipement homologue est engorgé ou a fortiori n'importe quel élément de la chaîne entre les deux, alors le système devrait cesser d'émettre de lui-même. Vu de ton programme, comme tu utilises des sockets qui eux-mêmes fonctionnent comme des tubes, alors l'appel système sera bloquant et ton programme restera en suspens sur « write() » jusqu'à ce que le tout se débloque.

    L'UDP en revanche, est plus un protocole « carte postale ». Chaque paquet est indépendant de ses prédécesseurs et, surtout, le réseau ne garantit PAS l'arrivée d'un datagramme. C'est utile pour faire des petites requêtes simples ou des notifications, par exemple une requête DNS. Un datagramme suffit à demander la résolution d'un nom de machine en son adresse IP, et la réponse peut très bien arriver indépendamment de toute application en cours de fonctionnement. Il y généralement un daemon qui s'occupe de ça et qui prend note de l'adresse en question quand elle arrive jusqu'à ce que quelqu'un la réclame. Ça s'utilise également pour certains flux lorsque l'instantanéité est plus importante que l'intégrité, typiquement un flux audio ou de la voix sur IP. Quelques paquets perdus provoqueront l'équivalent sonore d'un parasite, mais cela n'engorgera pas le réseau en demandes superflues, surtout si le paquet n'a plus d'intérêt s'il arrive trop tard.

    Par contre, ça ne sert pas à faire une communication continue : si c'est ce que tu utilises pour transmettre tes informations et que tu fais bien 30.000 appels par seconde, alors non seulement il y a de grandes chances pour que tes paquets se perdent, mais tu n'es pas assuré non plus qu'ils arrivent dans l'ordre à ton destinataire non plus ! C'est un piège quand on débute en programmation réseau et que l'on se rabat dessus pour éviter de fastidieux connect()/accept().

    Si tu ralentis ton programme avec des temporisations, tu vas certes soulager ton réseau mais si quelque chose d'autre vient à l'exploiter de son côté, alors les problèmes que tu rencontres risquent de réapparaître spontanément pour une cause complètement étrangère à toute ta chaîne de traitement.

    P.S. Obsidian
    Merci pour ce long message que je dois relire plusieurs fois et qui m'apporte plusieurs réflexions. Ce sont que des infos et remarques intérressantes.
    Je reconnais que j'ai tendance à écrire des tartines là où d'autres auraient synthétisé cela en quelques mots…

  16. #16
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2016
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2016
    Messages : 23
    Points : 19
    Points
    19
    Par défaut
    100000 micro secondes , rien ne me choque pour moi, l'ordonanceur de tache windows est cadencé a 5ms

  17. #17
    Futur Membre du Club
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Novembre 2016
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Novembre 2016
    Messages : 11
    Points : 9
    Points
    9
    Par défaut
    Bonjour en ce beau Dimanche de Décembre

    hobouu, juste pour info, je viens de relancer mon programme test usleep et nanosleep avec le code du début de ce post. Et je te confirme qu'à partir de 10000 et donc moins, la derive horaire ce fait bien ressentir et est significative.

    Obsidian, sur IP, là tu rentre dans mon expertise. Tout ce que tu dis est vrai. Je rajouterais juste qu'en UDP, le controle des paquets est possible, il suffit que cela soit ton process qui le gère car oui, la pile IP ne le fera pas.
    Dans mon cas, imaginons que je désires écrire un programme qui test les performances d'un routeur. Tu vois je génères des dizaines de milliers de paquet (sans session, ni contrôle) avec juste un marquage dans la Data. Et un autre programme, de l'autre côté du routeur qui réceptionne et indique combien de Datagramme il lui manque (via le marquage incrémentiel trouvé dans Data). Ainsi, j'obtiendrais une relation entre : Occupation CPU du routeur, nombre de paquet perdu, latence.

    Cependant, mon but n'est pas d'exploser le routeur et démontrer que je le met à genoux, mais bien de pouvoir réguler mon flux afin d'obtenir un tableau de performance comme par exemple : Pour 10K p/s, 20K p/s, 30K p/s ...

    D'où ma recherche de la temporisation. Je testerais cette semaine le tempo modéré toute les N Paquets emis et je ferais varié N.

  18. #18
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 372
    Points : 23 628
    Points
    23 628
    Par défaut
    Citation Envoyé par alexandre.dufoure Voir le message
    Obsidian, sur IP, là tu rentre dans mon expertise.
    Effectivement, j'avais omis le fait que tu te présentes dans ton profil comme architecte réseau. Donc, tu dois effectivement déjà maîtriser tout cela.

    Tout ce que tu dis est vrai. Je rajouterais juste qu'en UDP, le controle des paquets est possible, il suffit que cela soit ton process qui le gère car oui, la pile IP ne le fera pas.
    Oui, mais justement, il faut qu'il le fasse explicitement, c'est-à-dire avec des appels système dédiés à la gestion du réseau. Gérer le débit à coups de sleep, ça oblige à réveiller et rendormir sans arrêt le processus alors que le tout pourrait être confié aux sous-systèmes dont c'est la tâche et régulé comme il faut. En plus, si jamais ton réseau évolue, tu vas être obligé de recompiler ton programme pour modifier tes paramètres.

    Cependant, mon but n'est pas d'exploser le routeur et démontrer que je le met à genoux, mais bien de pouvoir réguler mon flux afin d'obtenir un tableau de performance comme par exemple : Pour 10K p/s, 20K p/s, 30K p/s ...

    D'où ma recherche de la temporisation. Je testerais cette semaine le tempo modéré toute les N Paquets emis et je ferais varié N.
    Et là encore, si ton système est pourvu d'une gestion réseau propre, cela ne devrait pas échoir à l'application elle-même. Si tu utilises Linux (ou tout autre solution basée dessus), regarde du côté de tc et des options --limit et --limit-burst de iptables.

    Tu devrais être intéressé par le Linux Advanced Routing & Traffic Control HOWTO en général et par les queuing disciplines en particulier.


  19. #19
    Membre expérimenté

    Homme Profil pro
    Responsable des études
    Inscrit en
    Mars 2009
    Messages
    553
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2009
    Messages : 553
    Points : 1 672
    Points
    1 672
    Par défaut
    Citation Envoyé par hobouu Voir le message
    100000 micro secondes , rien ne me choque pour moi, l'ordonanceur de tache windows est cadencé a 5ms
    Et après? Ca veut simplement dire qu'il y a un changement de tâche toutes les 5 ms, mais ça ne donne aucune indication sur le temps qui s'écoule entre deux exécutions d'une tâche donnée. Cela va dépendre du nombre de tâches en cours et des priorités qui y sont affectées.

Discussions similaires

  1. Réponses: 8
    Dernier message: 08/04/2011, 23h07
  2. [VBA]comment faire un temps arret de quelques secondes
    Par megapacman dans le forum Général VBA
    Réponses: 3
    Dernier message: 16/05/2008, 11h54
  3. Réponses: 7
    Dernier message: 27/01/2008, 12h08
  4. Réponses: 2
    Dernier message: 27/04/2007, 18h29
  5. Comment faire un clear sur un beufferedImage toutes les x secondes!
    Par jlassiramzy dans le forum EDT/SwingWorker
    Réponses: 10
    Dernier message: 26/07/2006, 13h18

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