Répondre à la discussion
Affichage des résultats 1 à 21 sur 21

[Python] Problème de lag de programme et essai de Timer python




  1. #1
    Loupsio

    [Python] Problème de lag de programme et essai de Timer python

    Bonjour
    J'ai actuellement un programme qui fonctione a merveille, à l'exception qu'après environ une journée a une journée et demi, quand je le récupère, l'ordinateur est inutilisable, beaucoup trop lent, cela me prend facile 1 a 2 minutes juste pour fermer python et valider l'arret du programme tellement il est lent

    une fois relancé il repars sans problème, si je reviens le voir 4-5 heures après, toujorus pas de problèmes, parfois meme le lendemain matin ca passe toujours, mais je suis tout de meme obligé de le fermer et le relancer régulièrement (2-3 jours) (en revanche meme si le pc est très lent, il continue bien d'executer le programme)

    Dans ce code il y a une fonction en boucle (exemple de code plus bas)
    Et je me demandais si c'est cette boucle infinie qui fait que le pc tourne au ralenti après un certain temps
    pourtant il fait 5 secondes de pause par cycle
    d'ou le fait que je me demande, est ce que lors des pauses : sleep(5) l'ordinateur est reelement en train de "ne rien faire" et "attendre" ou bien il considère que attendre est une tache (dans ce cas il ne s'arreterai jamais de tourner et ca pourrait expliquer pourquoi au bout d'un moment il en a marre)
    J'ai même ralenti ses cycles d'action la nuit avec des pauses de 60 secondes au lieu de 5 secondes pour que le lundi matin il soit frais et disponible (60 secondes d'attente pour une action dans la boucle d'envitron 2 secondes donc largement au repros proportionellement), mais il est toujours aussi lent a la reprise, et je suis obligé de le fermer et de le relancer tout de même.
    Et ducoup comment faire pour qu'il tourne toujours aussi fluidement que dans les 10-15 premières heures?

    J'ai essayé de passer par PyQt et QTimer pour lancer l'action avec un timer au lieu d'une boucle et de pauses dans la boucle, mais tout les exemples que j'ai vu semblent bien au dessus de mes compétences (pas de code simple en 4-5 lignes, toujours des créations de classes, avec des structures et des arguments qui ne me parlent absolument pas, un niveau au dessus du mien qui ne suis absolument pas programmeur de formation)

    sinon j'ai essayé avec gobject dont timeout_add(1000,maFonction), mais je me retrouve avec un message : 'module' has no attribute timeout_add ou un message du genre (peut etre parce que je suis sous python3, beaucoup beaucoup d'exemples de codes sont sous python2.7 mais rarement python3) ducoup gobject n'a jamais voulu marcher pour moi quand j'utilise timeout_add()
    Mais au final je ne suis même pas sur que passer par un autolancement toutes les x secondes plutot qu'une boucle en pause pendant x secondes, corrigerait ce problème

    Exemple court :
    Code:
    def lancerProg():
            i=0
    	while i==0:
    		%% faire des trucs, (entre autre aller chercher une donnée sur internet)
    		%% ouvrir un fichier texte
    		%% ecrire la donnée récuperée, dans le fichier texte
    		%% fermer le fichier texte
    		if nuit=T:
    			sleep(60)
    		else:
    			sleep(5)
    fen=Tk()
    t=Timer(1,lancerProg)
    t.start()
    fen.mainloop()
    je précise que le timer dans la fenetre Tk c'est parce que dans ma fenetre il y a des boutons et des zones de texte, et que sans ce timer, une fois le programme lancé je ne pouvais pas agir sur ma fenetre (cliquer sur les boutons ou ecrire dans les zones)


    Ducoup cettre structure fait exactement ce que je souhaite mais au bout d'une journée (parfois un peu plus) l'ordinateur et super long et agrandir le fenetre python, ou meme deplacer des elements a l'écran, cliquer sur "fermer" o ecrire dans ma fenetre Tk... prend beaucoup trop de temps alors que les 10 premières heures (plus ou moins) c'est nickel, fluide, aucun souci ....

    Si nécessaire, je suis sous ubuntu16 et j'utilise python3, mais je pense pas que ca change quoi que ce soit

    -----


  2. Publicité
  3. #2
    minushabens

    Re : [Python] Problème de lag de programme et essai de Timer python

    Tu peux suivre l'occupation de la mémoire dans une autre fenêtre. Il y a un outil sous ubuntu qui fait ça bien. Parce que ça ressemble à une histoire de mémoire allouée quelque-part dans la boucle et pas restituée quand on passe au pas suivant.

  4. #3
    Arzhur

    Re : [Python] Problème de lag de programme et essai de Timer python

    Voir même suivre l'utilisation CPU et I/O....autant ratisser large.

    Je ne sais pas à quoi minushabens fait référence comme outil, mais sar ou top marchent plutôt bien.


  5. #4
    pm42

    Re : [Python] Problème de lag de programme et essai de Timer python

    Citation Envoyé par minushabens Voir le message
    Tu peux suivre l'occupation de la mémoire dans une autre fenêtre. Il y a un outil sous ubuntu qui fait ça bien. Parce que ça ressemble à une histoire de mémoire allouée quelque-part dans la boucle et pas restituée quand on passe au pas suivant.
    Oui en effet. Juste de la CPU ne suffirait pas à faire ramer l'ordinateur. Donc la mémoire est le plus probable. Sinon, des ressources graphiques mais ce n'est pas par ça que je commencerais.

  6. #5
    Loupsio

    Re : [Python] Problème de lag de programme et essai de Timer python

    Merci a vous, je pense que minushabens fait référence au moniteur système (> gnome-system-monitor dans le terminal)
    pour l'occupation des ressources, j'ai lancé le moniteur, je verrai bien, mais je m'attend a ce qu'il me dise simplement que c'est python 3 qui me bouffe tout, mais il ne peut pas voir dans le programme si c'est a cause d'une variable énorme (normalement non vu que mes variables se réinitialisent a chaque itération mais bon...) ou si ca vient de tel ou tel partie, il me dira juste que c'est python qui consomme mes ressources je pense, non?

    Pour le CPU, j'ai jamais bien compris commen ca fonctionnait, dans le moniteur j'ai "historique d'utilisation de CPU" avec 4 courbes de couleurs differentes (CPU 1 à 4) et ca defile en temps réel, mais je ne sais pas a quoi les 4 CPU (courbes) correspondent.
    quant-à I/O je ne sais pas ou voir ca, en dessous de l'historique CPU j'ai juste "historique d'utilisation de la mémoire physique et du fichier d'échange) avec une droite représentant la mémoire et une droite à "0%" qui représente swap

    mais au final puisque des que je ferme le script et le réouvre, ca remarche, je pense que ces outils dirons juste que c'est du à python3, je sais pas si ils peuvent aller plus dans le détail
    Et c'est sur un ordinateur dédié donc il n'y a rien d'autre d'ouvert, juste le programme, les fenetres Tk du programme, et un Pdf qui se met a jour une fois par itération de boucle (mais pdf de quelques ko donc c'est pas ca qui prend la mémoire)

  7. A voir en vidéo sur Futura
  8. #6
    pm42

    Re : [Python] Problème de lag de programme et essai de Timer python

    Citation Envoyé par Loupsio Voir le message
    mais je ne sais pas a quoi les 4 CPU (courbes) correspondent.
    A chacun des coeurs de ton processeur. Il est capable de faire tourner 4 trucs en même temps, tu vois 4 courbes.

    Citation Envoyé par Loupsio Voir le message
    mais au final puisque des que je ferme le script et le réouvre, ca remarche, je pense que ces outils dirons juste que c'est du à python3, je sais pas si ils peuvent aller plus dans le détail
    Pour voir plus dans le détail, tu as des outils spécialisés : https://fr.slideshare.net/haypo/traq...es-avec-python

  9. #7
    minushabens

    Re : [Python] Problème de lag de programme et essai de Timer python

    il y a l'outil atop qui surveille le système et produit un log. C'est moins joli mais plus utile que les courbes du system-monitor.

  10. Publicité
  11. #8
    Arzhur

    Re : [Python] Problème de lag de programme et essai de Timer python

    mais au final puisque des que je ferme le script et le réouvre, ca remarche, je pense que ces outils dirons juste que c'est du à python3, je sais pas si ils peuvent aller plus dans le détail
    Les outils vont te dire ce qui est sur-utilisé ( moi j'ai surtout des pb avec CPU/accès disque/RAM).

    Une fois que tu as le bon coupable, tu pourras trouver dans ton code ce qui cause la surcharge.

  12. #9
    Loupsio

    Re : [Python] Problème de lag de programme et essai de Timer python

    pm42, pas mal ce truc, dans les slides ils parlent de memory_profiler qu'a lair pratique , par contre le mode ligne par ligne c'est pour les scripts basique, linéaires (si ya des boucles ou des fonctions il te detaille pas a quel itération de la boucle ca a augmenté, t'as ne valeur unique par ligne quand bien meme ce serait dans une boucle, et le mode par temps, te dis quand quand (dans le temps), mais ne précise pas quelle partie du code se produit l'augmentation de l'utilisation de mémoire
    (je vais essayer quand meme le ligne par ligne, par contre faut mettre un @profile au dessus de chaque fonction une par une)

    je vais faire un tour aussi du coté d'atop

    arzhur, pour l'instant j'ai regardé la mémoire utilisé et les CPU, ce qui prend le plus de CPU pour l'instant s'appel "evince" (5%, mais le pc etait encore rapide puisque j'ai relancé le prog ce matin, je verrai demain si quelque chose est passé au dessus) c'est tombé a 0 lorsque j'ai arrêté le script
    et en terme de mémoire il n'y avait rien de choquant (a part un truc a 1.3Gio , mais toujours présent lorsque j'arrete le script, et que je ferme python donc c'est pas lié)
    Dernière modification par Loupsio ; 22/01/2018 à 15h52.

  13. #10
    Arzhur

    Re : [Python] Problème de lag de programme et essai de Timer python

    Donc en gros : RAM (cmb de ram au total ?) ok et CPU ok

    A combien est la charge quand ça rame ? Sur l'outil atop tu ce sont les champs avg1,avg5 et avg15


    Sinon un peu plus de détail sur ce que fait la boucle pourrait nous aider a voir ce qui peut bouffer la machine (parce que ouvrir/ecrire/fermer un fichier, si c'est "mal" fait tu peux faire tomber des grosses bécanes)

  14. #11
    Loupsio

    Re : [Python] Problème de lag de programme et essai de Timer python

    la boucle (en comptant les fonctions appelées dans la boucle) fait environ 330 lignes donc je vais pas tout copier,
    si j'enlève les fonction type "action utilisateur" ainsi que les fonctions types "alertes problemes" (envoi de mail et autre) et que je minimiseau "coeur" du programme, ca donnerait ca :
    Code:
    
    def connexion_site():
        password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
        password_mgr.add_password(None, "http:/...", "login", "mdp")
        handler = urllib.request.HTTPBasicAuthHandler(password_mgr)
        opener = urllib.request.build_opener(handler)
        page=opener.open("http://...")
        page2=page.read()
        soup = bs4.BeautifulSoup(page2, 'html.parser')
        return(soup)
    
        
    
    
    def ecrire_jour(valeur1,valeur2,valeur3):
        global jour,ancienjour,heure
        if jour==ancienjour: # meme journée que la fois précédente, le fichier existe déja, on ajoute les nouvelles valeurs
            tableau=open("DonneesDeSuivi/"+jour+".csv","a",encoding ="utf-8")
            tableau.write(jour+";"+heure+";"+valeur1+";"+valeur2+";"+valeur3+";"+"\n")
            tableau.close()      
        else:#on vient de changer de journée, il faut ecrire le header du fichier csv à la premiere itération de la journée
            tableau=open("DonneesDeSuivi/"+jour+".csv","w",encoding ="utf-8")
            tableau.write("Date;Heure;Température;Hygrométrie;Eclairage;Module\n")
            tableau.write(jour+";"+heure+";"+valeur1+";"+valeur2+";"+valeur3+";"+"\n")
            tableau.close()
            ancienjour=jour
    
        
    def lancer_R(graphique,typegraphe):
        graphique=[graphique+".csv"]
        command= ['Rscript']
        path2script= ['/path/To/Script/R/script.R']
        args=graphique+typegraphe
        cmd=command+path2script+graphique+typegraphe
        subprocess.check_output(cmd,universal_newlines=True)
    
    def lancerProg():
        global decompte,jour,ancienjour,heure,valeur, graphique,typegraphe
        i=0
        while i==0:
            try:# eviter que le programme se coupe  lors d'un problème wifi
                soup2=connexion_site()
                valeur1=recuperer_donnee1(soup2)#lance une fonction non copié ici qui recupere un id dans le html parsé (la valeur qui nous interesse)
                valeur2=recuperer_donnee2(soup2)
                valeur3=recuperer_donnee3(soup2)
                mois=strftime("%B %Y")
                heure=strftime("%H:%M:%S")
                jour=str(date.today())
                ecrire_jour(valeur1,valeur2,valeur3)   
            except:
                print('erreur réseau')
                ecrire_jour('','','')
            lancer_R(graphique,typegraphe)
    Dernière modification par Loupsio ; 23/01/2018 à 20h05.

  15. #12
    Loupsio

    Re : [Python] Problème de lag de programme et essai de Timer python

    PS : j'ai oublié, juste après la derniere ligne dans le code (message au dessus)
    il y a un
    Code:
    if nuit =T:
       sleep(60)
    else:
       sleep(5)

  16. #13
    Arzhur

    Re : [Python] Problème de lag de programme et essai de Timer python

    question idiote : le sleep est bien "dans" le while, et pas "après" ?

  17. #14
    polo974

    Re : [Python] Problème de lag de programme et essai de Timer python

    je pense que c'est :
    Code:
    if nuit == T:
        ...
    avec double égal pour faire le test...

    et ça manque de close()

    lance ton prog depuis une console avec un & au bout.
    ça le lance en tâche de fond.
    fais un ps pour connaître le numéro du process python (disons 1234).

    ensuite regarde le nombre de fichiers ouverts par ce process:
    ls -l /proc/1234/fd

    si le nombre augmente, c'est que tu as oublié de fermer des connexions...

    et puis quand tu fais:
    Code:
                mois=strftime("%B %Y")
                heure=strftime("%H:%M:%S")
                jour=str(date.today())
    il vaut mieux que tu ne changes pas de jour au milieu...

    la bonne façon de faire est de chopper une seule fois le time.time() et de formater ensuite avec la valeur:
    Code:
    >>> import time
    >>> tt=time.localtime(time.time())
    >>> tt
    time.struct_time(tm_year=2018, tm_mon=1, tm_mday=24, tm_hour=13, tm_min=55, tm_sec=14, tm_wday=2, tm_yday=24, tm_isdst=0)
    >>> mois=time.strftime("%B %Y",tt)
    >>> mois
    'January 2018'
    >>> heure=time.strftime("%T",tt)
    >>> heure
    '13:55:14'
    >>> jour=time.strftime("%F",tt)
    >>> jour
    '2018-01-24'
    >>>
    Le mieux est l'ennemi du bien, et c'est bien mieux comme ça...

  18. #15
    CM63

    Re : [Python] Problème de lag de programme et essai de Timer python

    Bonjour,

    Mais sinon, quand on met des sleep dans un programme commandé par un timer, cela veut souvent dire qu'on n'a pas compris le fonctionnement du timer. En principe tu as besoin de l'un ou de l'autre mais pas des deux.

  19. #16
    Loupsio

    Re : [Python] Problème de lag de programme et essai de Timer python

    Citation Envoyé par Arzhur
    question idiote : le sleep est bien "dans" le while, et pas "après" ?
    oui il est bien dans le while mais le problème ne vient pas de la, le programme en soi fonctionne très bien, avec un tableau qui me file des lignes espacées de 5 secondes le jour et espacées de 60 secondes la nuit
    Citation Envoyé par polo
    je pense que c'est :
    Code:

    if nuit == T:
    ...

    avec double égal pour faire le test...
    il y a bien un double =, c'est parce que j'ai reecris manuellement les lignes ici quand j'ai vu que j'avais oublié de le copier, mais dans le programme la structure ne pose pas de problème j'ai bien un bon signe de comparason, comme je disait, le programme en soi fonctionne a merveille (il m'aurait envoyé un message d'erreur si j'avais mis un "=" dans un "if" au lieu d'un "=="
    Et au final avant il n'y avait pas ceci, la boucle se terminait par un sleep(5) et c'était tout, j'ai rajouté le "if" pour tenter que l'ordinateur soit plus au repos la nuit au cas ou le lag viendrai du faite que travailler toutes les 5 secondes serait de trop
    mais le probleme de lag etait deja la quand il y avait juste un sleep(5) en continu sans condition de nuit ou de jour

    Citation Envoyé par polo
    et ça manque de close()
    De quoi est ce que tu parles?
    a chaque fois qu'il y a un open pour lire ou ecrire un fichier , il y a un close()
    a l'exception du " page=opener.open("http://...") "
    mais il n'y en avait pas dans les exemple d'utilisation (et il ne s'agit pas d'un open() comme pour les fichiers mais d'un ".open" je pense que la structure est différente et que pour la page il n'y a pas besoin de close)
    sinon je ne vois pas de quel close manquant tu parles

    Citation Envoyé par polo
    lance ton prog depuis une console avec un & au bout.
    ça le lance en tâche de fond.
    fais un ps pour connaître le numéro du process python (disons 1234).

    ensuite regarde le nombre de fichiers ouverts par ce process:
    ls -l /proc/1234/fd

    si le nombre augmente, c'est que tu as oublié de fermer des connexions...
    Je tente ca demain, merci

    Citation Envoyé par polo
    il vaut mieux que tu ne changes pas de jour au milieu...

    la bonne façon de faire est de chopper une seule fois le time.time() et de formater ensuite avec la valeur:
    Oui mais le les données sont ecrites dans un fichier par jour, j'ai donc besoin de savoir lorsque l'on change de jour pour qu'il ne continue pas d'écrire dans le meme fichier

    Citation Envoyé par CM63
    Mais sinon, quand on met des sleep dans un programme commandé par un timer, cela veut souvent dire qu'on n'a pas compris le fonctionnement du timer. En principe tu as besoin de l'un ou de l'autre mais pas des deux.
    Non en fait je souhaite lancer ceci par un timer a la place d'une boucle (dans l'espoir que le problème vient de la boucle mais si ca se trouve le probleme restera le même

    L'unique timer pour l'instant va lancer la boucle une seconde après que la ligne ait été executé, mais il ne permet pas de récurrence , si j'enlève la boucle, le programme en début de lancement va passer par le timer, attendre 1 seconde lancer une fois les étapes voulues, et s'arreter pour ne jamais repasser par la fonction "lancerProg" il ne la lance qu'une seule fois
    Son utilité ici (car en soi je pourrai m'en passer et lancer la fonction sans attendre) c'est de rendre la fentre d'interface TKinter "libre" (si je ne met pas ce timer, il lance la boucle direct mais ne permet pas d'utiliser l'interface TK trop occupé a circuler dans la boucle, alors qu'avec le timer pour une raison que j'ignore mais qui est bel et bien réelle, une fois la boucle lancée, je peux agir sur l'interface graphique et modifier des éléments qui vont changer ce que fait le programme dans la boucle (sans avoir a couper le programme et le relancer) en son absence impossible de changer ces éléments dans l'interface graphique tant qu'il est dans la boucle, je devais arreter le programme et changer ce que je voulais changer avant de lancer la boucle
    Mais il n'en reste pas moins que ce timer ne lance la fonction qu'une seule fois (d'ou l'utilisation d'une boucle)
    Dernière modification par Loupsio ; 24/01/2018 à 16h52.

  20. #17
    CM63

    Re : [Python] Problème de lag de programme et essai de Timer python

    Pour répéter une certaine action à intervalle de temps régulier tu peux aussi utiliser Scheduler :

    Code:
    from apscheduler.scheduler import Scheduler
    
    sched = Scheduler()
    sched.start()
    
    def some_job():
        print "Every 10 seconds"
    
    sched.add_interval_job(some_job, seconds = 10)
    
    ....
    sched.shutdown()

  21. #18
    polo974

    Re : [Python] Problème de lag de programme et essai de Timer python

    Citation Envoyé par Loupsio Voir le message
    ...

    Oui mais le les données sont ecrites dans un fichier par jour, j'ai donc besoin de savoir lorsque l'on change de jour pour qu'il ne continue pas d'écrire dans le meme fichier

    ...
    le pb que je soulevais, c'est que tu peux faire ton premier appel le soir à 23:59:59.9999 et le suivant le lendemain à 00:00:00.0001 :


    mois=strftime("%B %Y")
    heure=strftime("%H:%M:%S")
    .... les douze coups de minuit ...
    jour=str(date.today())

    et oups, le jour et l'heure sont décorrélés...

    pour revenir à la fuite de quelque-chose (mémoire ou file descriptor ou que sais-je...)

    class urllib.request.HTTPPasswordMgr WithDefaultRealm
    Keep a database of (realm, uri) -> (user, password) mappings. A realm of None is considered a catch-all realm, which is searched if no other realm fits.
    donc normalement, un seul appel HTTPPasswordMgrWithDefaultReal m doit suffire.
    (je ne sais pas pourquoi le forum ajoute des espaces au milieu des mots...)

    et après le:

    Code:
    page=opener.open("http://...") 
    page2=page.read()
    il faut un :
    Code:
    page.close()
    ou bien utiliser le with...:
    Code:
    whith page=opener.open("http://..."): page2=page.read()
    qui s'occupera du close tout seul
    Dernière modification par polo974 ; 25/01/2018 à 09h40.
    Le mieux est l'ennemi du bien, et c'est bien mieux comme ça...

  22. #19
    Loupsio

    Re : [Python] Problème de lag de programme et essai de Timer python

    Ah, je ne savais pas pour le html, il n'y avait pas de .close() dans les exemples donnés lorsque je me suis renseigné, je rajouterai, ca doit jouer,
    Mais je crois avoir identifier le problème, je l'ai laissé tourner 2 jours et ce matin gros gros lag, et au niveau des ressources je vois "evince" 2 Gio, (cela correspond au lecteur pdf ubuntu aussi appelé "visonneur de documents") pourtant le pdf en lui meme ne fait que quelques ko,
    dans le script R appelé par python en subprocess, il y a un "plot()" et lorsqu'on est en subprocess, au lieu d'ouvrir une fenetre de plot comme c'est le cas en passant par la console R, il enregistre par défaut en tant que pdf nommé "Rplots.pdf", mais ducoup peut etre que avec juste la ligne "plot" il ne referme pas automatiquement le fichier, donc j'ai encadré le plot par
    Code:
    pdf("nom.pdf")
    plot(x,y)
    dev.off()
    si ce n'est pas suffisant, peut etre que le lecteur pdf ubuntu n'aime pas les "mises a jour" de pdf sans fermer "evince" entre chaque mise a jour lorsqu'il est réécrit,
    Dernière modification par Loupsio ; 25/01/2018 à 13h14.

  23. #20
    polo974

    Re : [Python] Problème de lag de programme et essai de Timer python

    et pour ça:
    .... les douze coups de minuit ...

    as-tu vu le pb (qui a très peu de chance d'arriver, mais quand même...) ?
    Le mieux est l'ennemi du bien, et c'est bien mieux comme ça...

  24. #21
    Loupsio

    Re : [Python] Problème de lag de programme et essai de Timer python

    as-tu vu le pb (qui a très peu de chance d'arriver, mais quand même...) ?
    Avec l'heure?
    oui, qu'il passe sur "heure=..." à 23:59:59 et qu'il passe sur la ligne "jour=today" a 00:00:00 et qu'il considère en fin de journée "b" 2h59 alors qu'il etait entre la journée "a" et la journée "b"

Discussions similaires

  1. Problème sur mon programme python
    Par manutpe69 dans le forum Programmation et langages, Algorithmique
    Réponses: 8
    Dernier message: 19/03/2017, 19h05
  2. [Python] subprocess, lancer un autre programme avec python
    Par Loupsio dans le forum Programmation et langages, Algorithmique
    Réponses: 10
    Dernier message: 30/11/2016, 18h56
  3. en python le multi tache n'est pas possible alors pourquoi les threads existent sur python?
    Par docEmmettBrown dans le forum Programmation et langages, Algorithmique
    Réponses: 5
    Dernier message: 10/06/2015, 15h47
  4. Programme python
    Par THESO dans le forum Programmation et langages, Algorithmique
    Réponses: 5
    Dernier message: 20/09/2013, 21h52
  5. petit problème dans mon programme python
    Par souchi6 dans le forum Programmation et langages, Algorithmique
    Réponses: 2
    Dernier message: 05/01/2013, 14h13