Journal Mini-projet (python): un démon système pour gérer des raccourcis clavier

Posté par . Licence CC by-sa.
20
12
août
2019

Sommaire

Voici un petit projet du dimanche qui pourra éventuellement servir à ceux d'entre vous qui ont un petit serveur audio ou une raspberry-pi pour de la domotique.

Le titre n'est peut-être pas très clair, mais l'objectif est relativement simple: il faut exécuter des commandes lorsque certaines combinaisons de touches sont envoyés. Par exemple voici un extrait de ma configuration:

[/dev/input/event0]
KEY_STOP =
    mpc clear
    mpc random off
    mpc add /
KEY_FORWARD     = mpc next
KEY_BACKWARD    = mpc prev
KEY_0 =
    mpc clear
    mpc load --range=0 Radios
    mpc play
KEY_1 + KEY_0 =
    mpc clear
    mpc search album 'Truth Is a Beautiful Thing' | mpc add
    mpc play

Comme il n'y a pas d'environnement graphique sur la machine en question, j'ai décidé de récupérer les entrées au niveau de evdev.
Il existe déjà un projet similaire du même nom (https://github.com/gandro/input-event-daemon) mais celui-ci n'est plus maintenu. D'autre part, j'ai ajouté le support pour des combinaisons de touches.

Le résultat est ici pour ceux que ça intéresse: https://github.com/nlgranger/input-event-daemon
J'ai aussi ajouté un fichier de service systemd et un PKGBUILD pour archilinux.

Comme le résultat est assez simple et tient dans un seul fichier, je vais commenter certaines parties.

Lecture des combinaisons de touches

Quand je détecte le début d'une possible combinaison de touches, le programme attend un peu pour qu'elle se complète puis la valide.

Les fonctions asynchrones (async, await) sont pratiques pour gérer plusieurs boucles en parallèle. Ici, inutile d'utiliser des threads explicitement, lorsque le await device.async_read_one() bloque pour attendre une valeur, python saute automatiquement dans le corps d'une autre fonction asynchrone en cours.

async def event_handler(device, bindings, command_queue):
    while True:
        # lecture de la première touche
        event = await device.async_read_one()
        event = evdev.categorize(event)
        # on vérifie que c'est une frappe de touche
        if not isinstance(event, evdev.KeyEvent) or not event.keystate == evdev.KeyEvent.key_up:
            continue
        prefix = (event.keycode,)

        # tant que la série de touches coïncide avec plusieurs raccourcis, on attend d'autres entrée
        try:
            while is_ambiguous(prefix, bindings.keys()):
                event = await asyncio.wait_for(device.async_read_one(), timeout=1)
                event = evdev.categorize(event)
                if not isinstance(event, evdev.KeyEvent) or not event.keystate == evdev.KeyEvent.key_up:
                    continue
                prefix += (event.keycode,)
        # mais si aucune entrée n'arrive, on valide la série de touches
        except asyncio.TimeoutError:
            pass

        # ...

Lancement de commandes avec des droits restreints

L'ouverture des périphériques /dev/input/event nécessite (à raison) les droits root, donc le démon tourne aussi en root. Par contre je n'étais pas enchanté à l'idée de lancer mes commandes de raccourcis en root aussi. J'ai essayé d'ouvrir les entrées puis de changer l'utilisateur avec setgid mais ça n'a pas fonctionné.

La solution la plus élégante que j'ai finalement trouvée est de démarrer un processus indépendant sous un autre utilisateur et de lui communiquer les commandes à lancer via une queue. C'est facile à implémenter tout en assurant une bonne séparation des droits.

Cette configuration a toutefois un petit défaut: il faut gérer proprement la fermeture du démon, de son enfant et de la queue. Déjà, il y a un risque que les signaux comme le sigint du ctrl-C dans le terminal soient interceptés par l'enfant. Pour éviter ça, il faut supprimer complètement la gestion des signaux avant de démarrer l'enfant (via un fork) puis les rétablir dans le parent. L'enfant hérite quant à lui de la 'non-gestion' des signaux au moment du fork:

command_worker = multiprocessing.Process(
    target=run_commands, args=[command_queue])
signal.signal(signal.SIGINT, signal.SIG_IGN)
command_worker.start()

Ensuite il faut rétablir la gestion du signal SIGINT dans le démon, avec en plus notre code pour faire le ménage avant de quitter:

def cleanup(*kargs):
    # on notifie l'enfant de la fin
    command_queue.put_nowait(None)
    # puis on attend qu'il se termine
    command_worker.join()
    command_queue.close()
    # et on quitte
    logger.info("Exiting")
    sys.exit(0)


signal.signal(signal.SIGINT, cleanup)

Gestion d'une télécommande

Ça n'a rien à voir, mais j'en profite pour rappeler que LIRC n'est plus la seule solution pour utiliser des télécommandes infrarouges sous linux.
En effet, une partie de code a été transférée dans les pilotes côté noyau. Avec des pilotes comme sunxi-ir pour les cartes ARM allwinner, un périphérique evdev apparait pour le récepteur infrarouge. Il suffit ensuite communiquer au noyau la configuration de la commande avec la commande ir-keytable.

Par exemple sur ma carte Cubietruck, j'ai une rêgle udev comme ceci:

#/etc/udev/rules.d/70-ir-remote.rules                                                                                                                       
ACTION=="add", ATTRS{name}=="sunxi-ir", RUN+="/usr/bin/ir-keytable -c -w /lib/udev/rc_keymaps/avermedia_rm_ks.toml --sysdev rc0"
  • # droits root non nécessaires

    Posté par . Évalué à 3 (+2/-1).

    L'ouverture des périphériques /dev/input/event nécessite (à raison) les droits root, donc le démon tourne aussi en root.

    Euh, ici j'ai (debian 10, mais c'est aussi valide sur la 9):

    $ ls -lh /dev/input/event*
    crw-rw---- 1 root input 13, 64 août  12 16:14 /dev/input/event0
    crw-rw---- 1 root input 13, 65 août  12 16:14 /dev/input/event1
    crw-rw---- 1 root input 13, 74 août  12 16:14 /dev/input/event10
    crw-rw---- 1 root input 13, 75 août  12 16:14 /dev/input/event11
    crw-rw---- 1 root input 13, 76 août  12 16:14 /dev/input/event12
    crw-rw---- 1 root input 13, 77 août  12 16:14 /dev/input/event13
    crw-rw---- 1 root input 13, 78 août  12 16:14 /dev/input/event14
    crw-rw---- 1 root input 13, 66 août  12 16:14 /dev/input/event2
    crw-rw---- 1 root input 13, 67 août  12 16:14 /dev/input/event3
    crw-rw---- 1 root input 13, 68 août  12 16:14 /dev/input/event4
    crw-rw---- 1 root input 13, 69 août  12 16:14 /dev/input/event5
    crw-rw---- 1 root input 13, 70 août  12 16:14 /dev/input/event6
    crw-rw---- 1 root input 13, 71 août  12 16:14 /dev/input/event7
    crw-rw---- 1 root input 13, 72 août  12 16:14 /dev/input/event8
    crw-rw---- 1 root input 13, 73 août  12 16:14 /dev/input/event9
    

    Et du fait qu'au taf j'ai implémenté un toolkit pour framebuffer, je dirais qu'il suffit que l'utilisateur qui lance le soft appartienne au groupe input. Dans mon cas, il faut aussi le groupe video pour /dev/fb0, et malheureusement root parce que sinon pas moyen (ou alors pas trouvé lequel) de passer un TTY en mode graphique (pour virer le curseur entres autres, via ioctl( fd, KDSETMODE, KD_GRAPHICS, j'ai même essayé de chercher avec les capabilities, mais rien trouvé, faudrait que je cherche a nouveau).

    Ceci étant dit, moi, j'ai utilisé libinput, et pas evdev, que je pense lié à Xorg. Peut-être est-ce la raison.

    • [^] # Re: droits root non nécessaires

      Posté par . Évalué à 3 (+2/-0). Dernière modification le 12/08/19 à 20:18.

      Très juste, le groupe input suffit et je pourrais donc modifier le service systemd pour lancer le démon avec des droits plus restreints. Si je n'ai pas trop la flemme je regarderai aussi du côté des capabilities, que l'on peut là aussi gérer via systemd il me semble.

      • [^] # Re: droits root non nécessaires

        Posté par . Évalué à 1 (+2/-3).

        On n'est pas dredi, mais, je ne peux pas résister…

        le groupe input suffit et je pourrais donc modifier le service systemd pour lancer le démon avec des droits plus restreints

        Dans la ligner de commande, ou équivalent, utiliser chpst nobody:input [command] devrais faire le boulot.
        La commande chpst est fournie, chez Debian, via le paquet runit, et j'ai eu l'agréable surprise de constater en passant a Debian 10, une nouvelle implémentation officielle du méta-paquet "init": "runit-init" (c'est un peu pour ça que je me permets cette digression, faut que je vérifies certaines choses avec, et si ça déconne ou si je peux améliorer, voire comment aider, si y'a pas trop de tours autour du pot…).

        Pour les capabilities, c'est juste pas le rôle du système d'init de gérer ça, c'est le rôle du système de paquets, vu que, de ce que j'en comprend, c'est lié au fichier lui-même. Je reconnaît ne pas y comprendre grand chose, cela dit. Et puis, systemd gérera bientôt le boot, alors les paquets, qui sait?

        Plus sérieusement, je pense que la gestion par groupes est bien plus pertinente que la gestion par capabilities: déjà, moins de risques que la capability nécessaire soit la cap' DIEU (je me comprend, flemme de rechercher le lien dans lequel il était expliqué qu'une cap' était utilisée pour tout ce qui n'avais pas de catégorie, ce qui résultait en en une cap' "root"), de plus c'est plus portable, et «accessoirement», pas besoin d'être root pour installer le binaire, parce que de ce que je sais, pour donner a un binaire des capacités, il faut être root (cf remarque précédente sur mon niveau de compréhension du sujet).

        Bon, j'avoue ne pas encore connaître vraiment les bases de ce monde la, je ne sais pas en détails comment marche le système de droits: est-ce un processus sous root qui initialise tous le /dev avec divers user:groups? Se sert-il de capabilities? Je sais pas. Faudrait que j'aille jouer avec hurd, je pense que ça m'en apprendrais beaucoup sur le sujet, du fait de se baser sur une philosophie différente. Ou les BSD, chose que je me promets de faire depuis des années, mais a chaque fois je le fais que via VM, ça risque pas de me motiver…

        • [^] # Re: droits root non nécessaires

          Posté par (page perso) . Évalué à 9 (+6/-0).

          c'est lié au fichier lui-même.

          C'est plus compliqué que cela. Il est possible d'attacher des capabilities à un fichier pour qu'un utilisateur exécutant ce fichier ait ces capabilities. Mais il est aussi possible pour un processus de supprimer des capabilities. C'est ce dernier cas qui est utilisé avec systemd. Cela permet de se retrouver avec uniquement les capabilities dont on a besoin et donc de ne pas avoir la capability SYS_ADMIN (celle que tu appelle root à mon avis). Et donc même en étant root, il y a plein d'opération que ton processus ne peut pas faire.

          Les capabilites sont des permissions différents des permissions sur les fichiers. Tu as, par exemple, la capability SYS_BOOT qui te permet de redémarrer le système ou NET_RAW pour ouvrir des sockets raw. Que tu sois root ou pas, si tu n'as pas ces capabilities, tu ne peux pas faire l'opération. Inversement, tu peux faire ces opérations sans être root si tu as ces capabilities.

          Je pense que ça se discute, mais pour moi, c'est bien au système d'init de lancer les processus avec le moins de droit possible et donc être root sans capabilities par exemple.

          est-ce un processus sous root qui initialise tous le /dev avec divers user:groups? Se sert-il de capabilities?

          Les capabilities, c'est pour l'appel système ioctl( fd, KDSETMODE, KD_GRAPHICS évoqué plus haut, pas pour écrire dans un fichier.

          « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

          • [^] # Re: droits root non nécessaires

            Posté par . Évalué à 2 (+0/-0).

            Merci pour les explications.

          • [^] # Re: droits root non nécessaires

            Posté par . Évalué à -2 (+0/-4).

            Je pense que ça se discute, mais pour moi, c'est bien au système d'init de lancer les processus avec le moins de droit possible et donc être root sans capabilities par exemple.

            Ca va etre un beau b***** à débugger si chacun a son niveau va gérer les droits de ceci ou de cela.

            Non le système d'init n'a pas a gérer ce genre de choses. Il doit se reposer sur un système à part entière qui fait le travail. Mais jamais de la vie il doit le faire lui-même.

            systemd ça devient vraiment n'importe quoi.

            • [^] # Re: droits root non nécessaires

              Posté par . Évalué à 3 (+1/-0).

              systemd ça devient vraiment n'importe quoi.

              T'inquiètes, bientôt il intégrera le noyau, ça ira mieux après.

            • [^] # Re: droits root non nécessaires

              Posté par (page perso) . Évalué à 3 (+0/-0).

              Il doit se reposer sur un système à part entière qui fait le travail

              Sur quel système tu veux qu'il se repose pour faire un prctl ?

              « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

  • # quand je vois "demon système en python", je crains pour l'aututonomie de mon ordinateur portable.

    Posté par . Évalué à -3 (+0/-5).

    J'utilise wicd sur mon laptop et je le vois souvent utiliser une quantité non négligeable de temps CPU (peut monter à plus de 75%). Pour ma part je pense qu'utiliser un langage comme Python ou Ruby (je suis pas sectaire) pour ce genre d'outil est un gaspillage de ressources (et uneœ aberration écologique).

    • [^] # Re: quand je vois "demon système en python", je crains pour l'aututonomie de mon o

      Posté par . Évalué à 3 (+1/-0). Dernière modification le 15/08/19 à 14:00.

      Est-ce la faute du langage ou celle du développeur? Parce que si c'est rapport au fait des langages interprétés, je te rappelle que la quasi totalité des sites web dynamiques sont implémentés en PHP ou ruby, quelques uns en perl, mais rares sont ceux basés sur des CGI en C, C++ ou autre langage compilés.
      Accessoirement, python dispose, de mémoire, d'au moins un compilateur.
      Le HTML lui-même gagnerais énormément a être compressé, en terme d'efficacité ce truc est une aberration.
      Et, pour le coup, wicd sert plus a utiliser le web qu'internet.

      Moi, je pense que c'est aussi la faute aux utilisateurs: pourquoi tu utilises wicd? C'est pas comme s'il n'y avais pas moyen de s'en passer… et personnellement, je n'ai utilisé ce genre de truc que pour accéder a des réseaux non chiffrés (genre hotels), parce qu'ironiquement, je ne sais pas configurer mon système pour ces réseaux, alors que c'est tellement simple de le faire pour du wpa.
      Dans ta distribution, je n'ai aucun doute qu'une quantité non négligeable de choses se reposent sur du shell, du perl ou du python.

      Oups, j'ai marché dedans.

      • [^] # Re: quand je vois "demon système en python", je crains pour l'aututonomie de mon o

        Posté par . Évalué à 2 (+0/-0).

        Est-ce la faute du langage ou celle du développeur?

        La faute du développeur qui utilise un langage mal adapté à la situation.

        Parce que si c'est rapport au fait des langages interprétés, je te rappelle que la quasi totalité des sites web dynamiques sont implémentés en PHP ou ruby, quelques uns en perl, mais rares sont ceux basés sur des CGI en C, C++ ou autre langage compilés.

        Euh … Je parle initialement de daemon pouvant être utilisé sur un ordinateur portable. Donc oui c'est gênant d'avoir un daemon système qui utilise des cycles cPU pour rien. Et a l'heure du green IT, je pense qu'il faut se poser la question d'économie de ressources, de cycles CPU, et remettre en question ce genre de choix ne me parait pas délirant.

        Moi, je pense que c'est aussi la faute aux utilisateurs: pourquoi tu utilises wicd? C'est pas comme s'il n'y avais pas moyen de s'en passer…

        Aurais-tu des alternatives à me proposer ? C'est ce que j'ai de plus pratique aujourd'hui pour connecter mon ordinateur portable à divers réseaux lors de mes déplacements ou chez moi (wifi de mon domicile, chez la famille, sur mon smartphone, éventuellement comme tu dis pour accéder à des réseaux genre hotel).

        Dans ta distribution, je n'ai aucun doute qu'une quantité non négligeable de choses se reposent sur du shell, du perl ou du python.

        Pas forcément des trucs qui tournent en permanence sur ma machine. Et si c'est le cas je pense qu'il faut justement commencer à s'en débarasser.

        • [^] # Re: quand je vois "demon système en python", je crains pour l'aututonomie de mon o

          Posté par . Évalué à 2 (+0/-0).

          Aurais-tu des alternatives à me proposer ? C'est ce que j'ai de plus pratique aujourd'hui pour connecter mon ordinateur portable à divers réseaux lors de mes déplacements ou chez moi (wifi de mon domicile, chez la famille, sur mon smartphone, éventuellement comme tu dis pour accéder à des réseaux genre hotel).

          Perso, j'utilise juste wpasupplicant, mais comme je l'ai dis, je ne m'en sers que pour les réseaux wifi avec wpa, je ne sais pas configurer mon système pour les réseaux wep ou non protégés, donc, non, je n'ai pas d'alternative a te proposer.
          Enfin, sauf d'utiliser wpasupplicant, mais j'imagine que l'idée d'ajouter tes clés wifi a un fichier texte puis relancer un daemon ne te paraît pas pratique (pas besoin de les supprimer, il utilise la clé associée au réseau courant, jamais essayé dans la situation ou il y aurait 2 réseaux connus en même temmps).

      • [^] # Re: quand je vois "demon système en python", je crains pour l'aututonomie de mon o

        Posté par . Évalué à 7 (+5/-0).

        Et, pour le coup, wicd sert plus a utiliser le web qu'internet.

        Celle-là je ne l'avais pas relevée en première lecture. Tu peux développer STP ?

        • [^] # Re: quand je vois "demon système en python", je crains pour l'aututonomie de mon o

          Posté par . Évalué à 2 (+0/-0).

          C'était un demi trait d'humour. Ce que je voulais dire, c'est surtout qu'il est probable que de toute façon l'outil qui va le plus être utilisé est un navigateur web, et je serai peu surpris que ça bouffe bien plus que wicd, avec la tétrachiée de JS dans la majorité des sites web.
          Après, oui, forcément, on est pas obligé, on peu utiliser un client lourd (et dans le cas de thunderbird, j'ai bien l'impression qu'il inclue le moteur de rendu de FF, je me demande d'ailleurs ce que ça ferait d'ouvrir un mail avec du JS?) pour les mail, utiliser irc, faire du ssh & co, mais je crains que ça ne devienne marginal a notre époque.

          • [^] # Re: quand je vois "demon système en python", je crains pour l'aututonomie de mon o

            Posté par . Évalué à 3 (+1/-0).

            l'outil qui va le plus être utilisé est un navigateur web, et je serai peu surpris que ça bouffe bien plus que wicd, avec la tétrachiée de JS dans la majorité des sites web.

            Euh … Monter a 75% d'occupation CPU, c'est loin d'être négligeable, même si c'est moins qu'une page web avec du javascript dans tous les coins. Sinon j'ai remarqué aussi ce comportement avec HPLip sur mon poste fixe sus FreeBSD. Et juste dire "je m'en fous de la consommation CPU d'un process système, ya d'autres process qui consomment plus" je trouve pas ça terrible. Ce serait comle se dire "je m'en fous de la consommation de ma voiture (ou des rejets CO2), ya des camions qui roule sur la route et consomment (ou rejettent) bien plus"

            faire du ssh & co mais je crains que ça ne devienne marginal a notre époque.

            Je dois être marginal alors.

    • [^] # Re: quand je vois "demon système en python", je crains pour l'aututonomie de mon ordinateur portab

      Posté par (page perso) . Évalué à 4 (+1/-0).

      Il est de notoriété public que wicd est très inefficace (par exemple: https://bugs.launchpad.net/wicd/+bug/510275 ), du coup, ça ne m'étonne pas trop qu'il consomme beaucoup de CPU chez toi.

      « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

    • [^] # Re: quand je vois "demon système en python", je crains

      Posté par . Évalué à 3 (+1/-0).

      Et venir troller sur linuxfr pour exprimer des platitudes du genre « le software, c’est mieux quand ça va vite », ca fait du sens, écologiquement?

      Linuxfr, le portail francais du logiciel libre et du neo nazisme.

      • [^] # Re: quand je vois "demon système en python", je crains

        Posté par . Évalué à 1 (+1/-2). Dernière modification le 16/08/19 à 08:34.

        exprimer des platitudes du genre « le software, c’est mieux quand ça va vite »

        Tu ne sais pas lire … J'ai parlé de consommation inutile de cycle de CPU par l'utilisation d'un langage que j'estime mal adapté à un cas d'usage ( je ne prétends pas non plus avoir raison, c'est juste mon point de vue).

        • [^] # Re: quand je vois "demon système en python", je crains

          Posté par . Évalué à 2 (+1/-1).

          Je sais très bien te lire, t’es pas non plus le dernier à venir te plaindre de software bloaté même quand il sont écrit en language compile. Et t’es en tête de ligne quand il s’agit de venir chier sur systemd (tu l’as fait dans ce thread) et venir préconiser des systèmes d’init basé sur des scripts shell écrits dans des langages interprétés aux performances pitoyables, c’est assez ironique quand même, non?

          un bon développeur interprété peut écrire du code qui consomme moins qu’un développeur compilé médiocre. Limiter la performance d’un soft non trivial au langage montre surtout une grosse méconnaissance du développement software.

          En l’occurence, vu le bug donné au dessus, le problème à pas grand chose à voir avec le choix du langage, mais avec la décision de lancer 2 binaires toutes les 3 secondes.
          Dans le même tonneau, on peut aussi citer Facebook qui a choisi mercurial écrit en python plutôt que git écrit en c, parce que git ne passait pas a l’echelle Pour eux.

          Linuxfr, le portail francais du logiciel libre et du neo nazisme.

          • [^] # Re: quand je vois "demon système en python", je crains

            Posté par . Évalué à 0 (+1/-3). Dernière modification le 16/08/19 à 10:36.

            Et t’es en tête de ligne quand il s’agit de venir chier sur systemd (tu l’as fait dans ce thread) et venir préconiser des systèmes d’init basé sur des scripts shell écrits dans des langages interprétés aux performances pitoyables, c’est assez ironique quand même, non?

            Non. On parle de daemon systeme, pas de truc lancé juste une fois au démarrage.

            un bon développeur interprété peut écrire du code qui consomme moins qu’un développeur compilé médiocre.

            Un bon développeur compilé écrira du code qui consomme moins que le meilleur code écrit en langage interprété (au moins pour Python et Ruby), A ma connaissance le seul qui sort d lot est Perl qui est capable d'exécuter du code avec des perfs proches du code compilé.

            Dans le même tonneau, on peut aussi citer Facebook qui a choisi mercurial écrit en python plutôt que git écrit en c, parce que git ne passait pas a l’echelle Pour eux.

            Tu as des liens sur ce sujet ?

            • [^] # Re: quand je vois "demon système en python", je crains

              Posté par . Évalué à -1 (+0/-3).

              J'allais oublier …

              En l’occurence, vu le bug donné au dessus, le problème à pas grand chose à voir avec le choix du langage, mais avec la décision de lancer 2 binaires toutes les 3 secondes.

              Ah ? Et c'est bizarrement wicd qui utilise les cycles CPU de ces binaires ? ?

            • [^] # Re: quand je vois "demon système en python", je crains

              Posté par . Évalué à 1 (+1/-2). Dernière modification le 16/08/19 à 16:49.

              Non. On parle de daemon systeme, pas de truc lancé juste une fois au démarrage.

              excuses à la con.

              Un bon développeur compilé écrira du code qui consomme moins que le meilleur code écrit en langage interprété

              C’est pas ce que t’as dit au dessus. Tu noteras aussi qu’il est exponentiellement plus dur d’écrire du bon code compilé qu’interprete, en raison des abstractions des langages. Et je passe sur les problèmes de sécurité ouverts par c et c++.

              Tu as des liens sur ce sujet ?

              https://lmgtfy.com/?q=facebook+mercurial+git

              Linuxfr, le portail francais du logiciel libre et du neo nazisme.

              • [^] # Re: quand je vois "demon système en python", je crains

                Posté par . Évalué à 0 (+1/-3).

                excuses à la con.

                Du même niveau que mon interlocuteur. Mais vu que j'ai affaire à un fanatique de systemd, tout ce que je pourrai dire a son sujet ne sera qu'argument a la con.

                C’est pas ce que t’as dit au dessus.

                Ah bon ? Tu peux me remettre la phrase qui semble dire le contraire ? Parce que j'ai pu mal m'exprimer, ou écrire le contraire de ce que je pensais.

    • [^] # ou pas

      Posté par . Évalué à 5 (+4/-0).

      Tu aurais du lire de quel démon il s'agit. Vu l'application, le mien passe 99,999% (au pifomètre) du temps bloqué sur l'appel système qui attend un retour de la part d'evdev.
      J'aime le code optimisé, mais je n'optimise que les parties critiques pour lesquelles cette optimisation a une réelle utilité.

      • [^] # Re: ou pas

        Posté par . Évalué à 2 (+1/-1).

        Je ne voulais pas forcément parler de cette appli en particulier, mais je voulais parler de mon inquiétude a voir du python sur des démons systèmes d'une façon générale. Je suis pas certain que ce soit toujours une bonne idée.

    • [^] # Re: quand je vois "demon système en python", je crains pour l'autonomie de mon ordinateur portable.

      Posté par (page perso) . Évalué à 3 (+2/-0).

      Le langage Python a ses avantages et inconvénients. Il est clair que si on doit coder un logiciels de rendu par lancé de rayon, ou un logiciel de compression, ou de traitement d'image, bref un truc qui demande des perfs, on va regarder du côté de langages compilés.

      Un démon, c'est sensé tourner en continu, et donc tu te dis que si ça utilise des technologies non adaptées, ça va consommer grave. Alors je ne suis pas le développeur (ni même développeur), mais le démon en question doit scruter les appuis sur le clavier. Pour ça je pense qu'il existe des évènements, et ce programme va attendre un évènement avant de vraiment faire quelque chose*. En gros, la majorité du temps il va se tourner les pouces, et ce n'est que lors d'une frappe au clavier qu'il risque de consommer des ressources.

      Ce programme est destiné à une utilisation sur serveur, on ne va pas écrire un roman ou troller sur Linuxfr depuis cette machine, donc c'est très rarement qu'il va vraiment effectuer des tâches. Je ne crois donc pas que ça vaille la peine de coder cet outil dans un autre langage, et y perdre des heures, pour gagner quelques millisecondes de temps processeur, sur une machine qui de toutes façons n'est pas surchargée.

      *En fait j'avais codé un petit outil similaire, un script bash qui attendait des commandes au clavier avec une boucle et la fonction «read». Tant qu'il n'y avait pas d'appui au clavier, la fonction read bloquait la boucle, et il n'y avait aucune utilisation du CPU.

      Un LUG en Lorraine : https://enunclic-cappel.fr

    • [^] # Re: quand je vois "demon système en python"…

      Posté par . Évalué à 1 (+1/-0).

      Tu as une observation. Qu'est-ce qui te permet d'en faire une corrélation et à fortiori une cause ?

      • [^] # Re: quand je vois "demon système en python"…

        Posté par . Évalué à 0 (+1/-3). Dernière modification le 19/08/19 à 08:55.

        Disons que j'ai plus qu'une observation :
        - j'observe que wicd me prend un gros pourcentage de temps CPU.
        - j'observe ussi que sur mon fixe, il arrive à hp-systray de me faire la même chose
        - les deux sont écrits en python
        - a chaque fois que j'ai vu ma batterie se décharger anormalement vite, wicd prenait beaucoup de temps CPU, bien plus que les onglets Firefox ouverts.

        De plus :
        - il est reconnu qu'un programme python s'exécute plus lentement (parfois beraucoupo plus lentement selon le programme) que le même programme écrit dans un langage compilé - exemple: le C). Mais ce problème ne concerne pas que Python: un site écrit en Ruby/Rails est assez lent (parfois plus lent qu'un site écrit en python). Le seul à bien s'en sortir à ce niveau (à ma connaissance), c'est le Perl ( dans une de mes missions, un outil avait été écrit en Perl plutôt qu'en python car Python s'en sortait pas niveau perfs). Et je ne parle pas de PHP qui n'a pas forcément une bonne réputation (mais que je ne connais plus suffisamment pour en parler). La lenteur ne vient pas du fait que les cycles CPU sont plus lent à s'exécuter pour un probramme python ou Ruby que pour un programme Perl ou C. Le fait est bien que Python ou Ruby utilisent plus de cycle CPU (donc plus d'énergie).

        Et je pousse ma réflexion en me disant que l'économie d'énergie n'est pas juste un priblème de portable, mais qu'elle concerne aussi les serveurs. Et qu'un jour on devra probablement remettre en question nos façons de faire. Peut-être n'ira-t-on pas jusqu'à utiliser de l'asselmbleur partout (pour caricvaturer un peu), mais a mon avis ça passera au moins par un gros travail sur les perfs des runtimes des langages tels que Python, Ruby ou PHP.

        Donc oui, ça me fait peur d'avoir un démon python qui s'exécute sur une machine qui a besoin d'éconoimiser de l'énergie. Alors effectivement, dans le cas présent, ça ne pose probablement pas problème puisque le programme attend des evenements clavier. Par contre je ne suis pas sur que ce soit aussi neutre pour un prog qui fait du pooling à intervales réguliers par exemple, intervalles suffisamment proches pour que le code soit sollicité souvent). Maintenant mon raisonnement n'est peut-être pas bon, j'en ai conscience, ou je le pousse peut-être un peu trop. Mais dans ce cas, j'apprécie d'avantage ta démarche, qui consiste à me faire expliquer mon point de vue, pour me corriger si nécessaire, que celle de certains autres intervenant (un en particulier).

        • [^] # Re: quand je vois "demon système en python"…

          Posté par . Évalué à 1 (+1/-0).

          il est reconnu qu'un programme python s'exécute plus lentement (parfois beraucoupo plus lentement selon le programme) que le même programme écrit dans un langage compilé - exemple: le C). Mais ce problème ne concerne pas que Python: un site écrit en Ruby/Rails est assez lent (parfois plus lent qu'un site écrit en python). Le seul à bien s'en sortir à ce niveau (à ma connaissance), c'est le Perl ( dans une de mes missions, un outil avait été écrit en Perl plutôt qu'en python car Python s'en sortait pas niveau perfs). Et je ne parle pas de PHP qui n'a pas forcément une bonne réputation (mais que je ne connais plus suffisamment pour en parler). La lenteur ne vient pas du fait que les cycles CPU sont plus lent à s'exécuter pour un probramme python ou Ruby que pour un programme Perl ou C. Le fait est bien que Python ou Ruby utilisent plus de cycle CPU (donc plus d'énergie).

          Ici tu décrit beaucoup de « on dit » et de généralités…

          Un programme peut être bridé par 3 choses différentes :

          • la CPU, on parle de CPU bound (ou intensive)
          • la mémoire, on parle de memory bound
          • les entrée/sortie, on parle de IO bound

          Pour chacun des cas on peu distinguer plusieurs limites différentes possibles.

          Un "deamon" ça n'a pas de profile de performance particulier. Ça peut demander du CPU, mais ça peut par exemple poser des problèmes de mémoire. Par exemple, un programme qui aura une longue durée de vie peut souffrir de fragmentation de sa mémoire. Au cours de sa vie il va utiliser et libérer de la mémoire, mais il doit faire attention :
          - les fuites mémoire (qui existent avec des garbage collector comme sans) peuvent faire consommer énormément de mémoire à un tout petit programme
          - la fragmentation de la mémoire au fur et à mesure de son exécution le programme laisse des "trous" non-utilisé de mémoire qui ne sont pas forcément réutilisés (trop petits, non adressables,…)

          Il y a différentes façons de mitiger ses problèmes (pour ce dernier point il est possible de créer des pools de structures qui seront réutilisées plutôt qu'allouer ou il est possible d'avoir un garbage collector qui vient compacter la mémoire à son passage entre autres stratégies).

          Tout ça pour dire qu'affirmer que tel langage n'est pas performant en général est plutôt succin et demande à regarder plus en avant quel genre de performance on souhaite et quels algos sont mis en place. Enfin il est fréquent qu'un programme soit fait de différents langages. CPAN contient énormément de code C qui possède juste une API perl. Je ne connais pas ussi, mais ce serait intéressant de savoir ce que fait wicd lorsqu'il utilise autant la CPU.


          nlgranger, pourquoi utilise-tu 2 boucles imbriquées ? Tu pourrais n'en utiliser qu'une seul ça éviterais de te répéter.

          D'autre part ton code de la ligne 78 à 86 me semble pouvoir être écrit plus simplement. prefix est sensé être une clef de ton dictionnaire bindings donc tu peux le récupérer et s'il existe lancer tes commandes sans avoir à itérer sur bindings :

          # Process command
          if prefix in bindings:
              logger.debug(f"handling {'+'.join(prefix)} on {device.path}")
              for cmd in bindings[prefix]:
                  command_queue.put_nowait(cmd)

          C'est moins pour moi une question de performance que de simplicité du code (pour totof2000 en terme de performance la différence entre les 2 codes sont non seulement que l'un fait un petit peu moins de choses, mais aussi qu'il fait moins de saut (moins de boucle, moins de if/continue/break), les sauts sont une plaie pour la CPU qui essaie de commencer son travail en avance (pipelining) et doit donc jeter tout le décodage qu'elle a fait pour rien).

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.