Forum Programmation.php Optimiser script php via multithread

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
1
29
jan.
2020

Pour un ensemble de fonctions qui doivent être exécutées et retourner un résultat rangé dans une variable commune : est-ce possible d’exécuter les fonctions en même temps plus tôt que d'attendre qu'elles s’enchaînent l'une après l'autre ?

Par exemple avec le script suivant, peut-on faire chuter son temps d’exécution de 3 secondes à une seconde ?

<?php

$content .= ma_fonction();
$content .= ma_fonction();
$content .= ma_fonction();

echo $content;

function ma_fonction(){
    sleep(1);
    return "Hello World -";
}
?>
  • # Dodo

    Posté par  . Évalué à 2.

    Tu enleve sleep(1) ? :)

    • [^] # Re: Dodo

      Posté par  (site web personnel) . Évalué à 2. Dernière modification le 29 janvier 2020 à 16:56.

      Ou Pluto le remplacer par usleep(333333).

      • [^] # Re: Dodo

        Posté par  . Évalué à 2.

        Le sleep n'est la que pour simuler un temps de travail dans une fonction d'exemple. Le but n'est point un Hello World mais réduire l'impacte temps d'un gros script 😋

  • # Parallel

    Posté par  (site web personnel) . Évalué à 4.

    Hello,

    Tu peux jeter un œil du côté de Parallel

    Jérôme.

    • [^] # Re: Parallel

      Posté par  . Évalué à 1.

      Merci ça a l'air d'être ce qu'il faut. Manque juste un petit exemple (c'est étonnant d'habitude il y en a plein en commentaire sur php.net).

      • [^] # Re: Parallel

        Posté par  (site web personnel) . Évalué à 3.

        Tu as un exemple sur le github du code de l'extension.

        <?php
        $runtime = new \parallel\Runtime();
        
        $future = $runtime->run(function(){
            for ($i = 0; $i < 500; $i++)
                echo "*";
        
            return "easy";
        });
        
        for ($i = 0; $i < 500; $i++) {
            echo ".";
        }
        
        printf("\nUsing \\parallel\\Runtime is %s\n", $future->value());
        
        • [^] # Re: Parallel

          Posté par  . Évalué à 1.

          Gros merci, je vais tenter d'appréhender la nouvelle logique.

          Chtites questions :

          1. Est-ce compatible ARM ?
          2. Comment détecter dans mon code PHP si la machine dispose du module ? (histoire de ne pas casser le script chez les gens n'ayant pas ce module)
          3. Est-ce stable ? (je vois qu'ici ils font installer la beta)
          • [^] # Re: Parallel

            Posté par  (site web personnel) . Évalué à 1.

            Hello,

            Malheureusement je pense qu'il va falloir sortit le compilateur et autres joyeusetés pour se faire un binaire PHP compatible (avec ZTS activé) et pouvoir installer le module.

            Pour l'ARM : aucune idée.

            Sinon il doit sans doute exister des images Docker toute prête ou presque.

            Jérôme.

            • [^] # Re: Parallel

              Posté par  . Évalué à 1.

              Malheureusement je pense qu'il va falloir sortit le compilateur et autres joyeusetés pour se faire un binaire PHP compatible (avec ZTS activé) et pouvoir installer le module.

              Un espoir de voir débarquer la feature out-of-box dans une version prochaine de PHP ? (le compilo, c'est pas trop mon truc surtout sur des machines de prod 😁)

  • # lancer plusieurs processus

    Posté par  (site web personnel) . Évalué à 2.

    La solution la plus simple n'est-elle pas de lancer plusieurs processus et laisser le noyau faire son boulot de répartition des processus entre processeurs / cores ?

    popen, exec, … les solutions ne manquent pas pour qu'un script PHP principal lance autant de processus (autre script PHP avec ta fonction) que besoin est.

    En fait, ça dépend de ce que tu veux faire. La fonction peut-elle bosser toute seule dans son coin ou doit-elle intéragir avec les autres fonctions similaires en cours d'exécution ? L'ordre d'arrivée des résultats doit-il respecter l'ordre de lancement des fonctions ? … autant de questions qui fait qu'une solution pourrait être choisie plutôt qu'une autre. On n'en sait pas assez pour te dire exactement quel est le meilleur choix.

    • [^] # Re: lancer plusieurs processus

      Posté par  . Évalué à 1.

      Le code n'est pas top secret, si tu veux jeter un oeil : https://gitlab.com/voxdemonix/cluster/blob/master/Monitoring/SysInfos.php (qui permet d'utiliser ce conky)
      Les deux fonctions que je souhaite modifier :
      conky_ServerInfos_All et conky_ServerInfos_PRIVACON4

      L'ordre d'arrivée des résultats doit-il respecter l'ordre de lancement des fonctions ?

      Non ça n'a aucune importance. Tout au plus veiller à ce que deux commandes ne mettent pas a jours une infos ou éditent le fichier bdd en même temps.

      La fonction peut-elle bosser toute seule dans son coin ou doit-elle intéragir avec les autres fonctions similaires en cours d'exécution ?

      Ça dépends des fonctions. Certaines interagissent via des variables globales, d'autres peuvent bosser solo.

      • [^] # Re: lancer plusieurs processus

        Posté par  (site web personnel) . Évalué à 1.

        Les fonctions dans Sysinfo.php ne font que retourner des données, il n'y a pas la partie stockage (en fichier ou bdd), mais de toute façon le "en même temps" n'a pas vraiment de sens vu que le système de fichier ou le moteur de la base de données gèreront tous seuls comme des grands les verrous d'accès en écriture.

        A priori rien n'empèche d'appeler plusieurs fois ces fonctions dans des proccesus différents. Ca doit rouler.

        • [^] # Re: lancer plusieurs processus

          Posté par  . Évalué à 1.

          A priori rien n'empèche d'appeler plusieurs fois ces fonctions dans des proccesus différents. Ca doit rouler.

          Comment ?

          • [^] # Re: lancer plusieurs processus

            Posté par  (site web personnel) . Évalué à 1.

            Désolé du retard dans la réponse, je suis actuellement en Chine (décalage horaire et cette histoire de coronavirus, ça occupe un peu).

            Ton script php principal doit lancer des scripts php secondaires pour lancer des fonctions. Ces scripts secondaires doivent être lancés comme suit dans le script principal :

            system("php script1.php < /dev/null > /dev/null 2> /dev/null &");
            system("php script2.php < /dev/null > /dev/null 2> /dev/null &");
            system("php script3.php < /dev/null > /dev/null 2> /dev/null &");

            Cet exemple lance 3 scripts qui s'executeront en parallèles, le script principal rendra la main immédiatement.
            Les /dev/null en entrée et en sortie sont importants, sinon les scripts ne s'executeront pas en parallèles.

            • [^] # Re: lancer plusieurs processus

              Posté par  . Évalué à 1.

              Merci pour ta réponse 😉

              Les /dev/null en entrée et en sortie sont importants, sinon les scripts ne s'executeront pas en parallèles.

              Cela empêche toute communication entre les process non ? (sauf peut-être a passer par un fichier se qui n'est pas tip top pour les I/O)

              • [^] # Re: lancer plusieurs processus

                Posté par  . Évalué à 2.

                dans tes interrogations précédentes, tu semblais vouloir scripteur du monitoring et afficher les retour dans conky

                peut-être vaut-il mieux alors avoir plusieurs scripts dédiés,
                plutot qu'un gros script que tu vas lancer 3 fois pour gérer des trucs différents.

                ou alors un seul script avec des options (mode1, mode2, mode3) pour interroger différents capteurs selon le mode.

                Le script sera alors plus rapide.

                et si un script doit récupérer plusieurs capteurs pour faire une et une seule sortie,
                alors à toi de coder pour faire des executions en parallèle de tes capteurs.

                • [^] # Re: lancer plusieurs processus

                  Posté par  . Évalué à 1. Dernière modification le 01 février 2020 à 20:14.

                  peut-être vaut-il mieux alors avoir plusieurs scripts dédiés,

                  Oui cette solution m'avait déjà traversé l'esprit et est très simple à mettre en place côté conky (sauf erreur de ma parti, en bash il suffit de concaténer des retours de plusieurs curl avec en fin de commande &). Mais j'essaye de m'en tenir à une seule et unique requête réseau par machine.

                  ou alors un seul script avec des options (mode1, mode2, mode3) pour interroger différents capteurs selon le mode.

                  C'est à ce genre de procédé que je songeais en effet.
                  Ainsi par ex le script s'auto-appelerait avec un paramètre GET (si on sait en passer via PHP) pour lancer d'un côté les commandes dépendant du retour de "top", de l'autre les commandes récupérant les infos sur les storage, etc.
                  Mais dans l'exemple énoncé précédemment, je ne vois pas comment récupérer dans une variable dans mon script principale le retour si on le renvoie vers /dev/null. Et donc comment reconstruire ma variable de sortie sans passer par un fichier qui servirait de mémoire interprocess (et qui augmenterait l'impacte machine).

              • [^] # Re: lancer plusieurs processus

                Posté par  (site web personnel) . Évalué à 1.

                Cela empêche toute communication entre les process non ? (sauf peut-être a passer par un fichier se qui n'est pas tip top pour les I/O)

                Passer les données par un fichier n'est pas un problème, vu le peu de données, il va rester dans le cache en mémoire, du coup ça va aller très vite. Et puis bon, linux, tout est fichier, c'est dans la philosophie du truc.

                Et oui, faire des scripts spécialisés c'est forcément mieux que de lancer un gros script plusieurs fois, mais c'est un peu plus de boulot à mettre en place.

                • [^] # Re: lancer plusieurs processus

                  Posté par  . Évalué à 1.

                  Passer les données par un fichier n'est pas un problème, vu le peu de données, il va rester dans le cache en mémoire, du coup ça va aller très vite. Et puis bon, linux, tout est fichier, c'est dans la philosophie du truc.

                  C'est plus pour les stockages que je m'inquiète. Le script utilise deja un xml pour stocker des données, mais est optimisé au max pour diminier les ecritures (OS sur cartes SD).
                  Je vais peut être implémenter cette methode avec une condition pour ne l'appliquer que quand tmp est en RAM (si j'arrive a le détecter depuis PHP).

                • [^] # Re: lancer plusieurs processus

                  Posté par  . Évalué à 1. Dernière modification le 03 février 2020 à 03:32.

                  L'implé complête prend 2 secondes d’exécutions de plus 🤔

                  • [^] # Re: lancer plusieurs processus

                    Posté par  . Évalué à 1. Dernière modification le 04 février 2020 à 01:33.

                    Rectification, quand on corrige les fôôôtes et la logique, ça fonctionne mieux ! 😋
                    Sur ARM il y a un gain de 1secondes (soit entre 25% et 33%), sur X64 le temps d’exécution est divisé par deux.

                    Merci à tous. En attendant le support du multithreading out of box, cette solution me conviendra 🙂

Suivre le flux des commentaires

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