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

Lazarus Pascal Discussion :

Petit souci avec TProcess et la taille du buffer de sortie [Lazarus]


Sujet :

Lazarus Pascal

  1. #1
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 947
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 947
    Points : 15 403
    Points
    15 403
    Par défaut Petit souci avec TProcess et la taille du buffer de sortie
    Bonjour,

    Pour des données pesant 159 octets (c'est variable, c'est pris dans des fontes) et un BUFSIZE défini à 2048, à l'exécution j'ai d'abord un ShowMessage de 15 octets suivi d'un autre ShowMessage du reste, soit 144 octets.
    Vous trouvez ça normal, vous ?

    Ce code va me servir à récupérer des données qui se suivent, dans les fichiers .ttf et .otf.
    Je me suis sans doute fourvoyé quelque part, mais où ?

    Je précise que la sortie du TProcess, enregistrée sur le disque et examinée dans un éditeur hexa, ne montre rien d'anormal : toutes les lignes (7) se terminent de la même manière avec le même octet, ".", d'une valeur de "0A".

    Pour cet exemple, il s'agit de la fonte LUCON.TTF.
    Je mets les deux premières lignes de l'éditeur hexa, puisque le souci est sur la première ligne vous pourrez comparer les deux "." :
    Nom : 2premièreslignes.png
Affichages : 115
Taille : 10,1 Ko

    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    procedure TForm1.Button2Click(Sender: TObject);
    const
      BUFSIZE = 2048; // Buffer size for reading the output in chunks
    var
      i: Integer;
      AProcess     : TProcess; // script.sh
      BytesRead    : LongInt;
      Buffer       : array[0..BUFSIZE-1] of char;
    begin
      for i := 0 to BUFSIZE-1 do Buffer[i] := '0'; // initialisation du buffer
      AProcess := TProcess.Create(nil);
      with AProcess do begin
        Options := [poUsePipes];
        Executable := Application.Location+'script.sh';
        for i := 0 to 0 do begin // fast test
        //for i := 0 to Count-1 do begin // full job
          Parameters.Clear;
          Parameters.Add(CacheItem.FileName); // le chemin de la fonte + le nom de la fonte
          try
            AProcess.Execute;
            repeat
              if Output.NumBytesAvailable > 0 then begin
                BytesRead := OutPut.Read(Buffer, BUFSIZE);
                ShowMessage(IntToStr(BytesRead)); // d'abord 15 soit 14+1 (1re ligne), puis 144
                MemoVisu.Text:= MemoVisu.Text + Copy(Buffer, 1, BytesRead);
              end
              else
                Sleep(1);
            until (not Running) and (Output.NumBytesAvailable = 0);
            ShowMessage(IntToStr(ExitStatus)+' '+IntToStr(BytesRead)); // 0 144
          finally
            //
          end;
        end; // for i...
        Free;
      end;
      MemoVisu.Lines.SaveToFile('/tmp/memovisu.txt'); // clic-droit propriétés --> 159 octets, soit 15 + 144
    end;
    La sortie complète, récupérée par le script qui fait tourner un outil de FontForge, et envoyée dans un TMemo :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Lucida Console
    Regular
    Lucida Console Regular; B&H alpha25
    Lucida Console
    Version 1.60
    LucidaConsole
    Lucida is a registered trademark of Bigelow & Holmes Inc.
    PS : j'ai écrit Buffer: array[0..BUFSIZE-1] of char; mais je vois parfois sur le web la phrase Buffer: array[1..BUFSIZE] of char;. C'est mieux ?
    En tout cas (comme je m'en doutais), utiliser l'une ou l'autre formule ne change rien au résultat et au comportement : 2 ShowMessage, , tout comme "descendre" la BUFSIZE de 2048 à 256.

    Une ou des idée(s) ?
    Merci !
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  2. #2
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 815
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 815
    Points : 13 531
    Points
    13 531
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Vous trouvez ça normal, vous ?
    Ca ne me choque pas.

    Le principe est asynchrone, tu lis ce qui est disponible à un temps T et tu as certainement déjà bouclé plusieurs fois avant même que le premier caractère soit disponible, avant même que l'app ait fini son initialisation.
    ShowMessage a ici surtout pour effet d'ajouter un long Sleep (jusqu'à ce que tu quittances le message) qui laisse à l'application le temps de terminer le job. Si tu utilisais un autre système non bloquant (ex. OutputDebugString) tu verrais certainement beaucoup plus de petits paquets.

    Sleep(1) n'a qu'un intérêt très limité ici, voire aucun. Lorsque je redirige les sorties standards, je ne contrôle en général que toutes les 100ms (si le buffer est vide). Il n'y a que s'il est plein (et pas non vide) que je lance immédiatement une deuxième récupération.

  3. #3
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 947
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 947
    Points : 15 403
    Points
    15 403
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Ca ne me choque pas.
    Ouf !

    Merci d'avoir pris le temps de regarder tout ça et d'y avoir répondu.

    J'ai donc changé Sleep(1) en Sleep(100), les données affichées par les ShowMessage ne sont pas les mêmes mais ce n'est pas grave au bout du compte car les données finales, celles dont j'ai besoin, sont OK.

    Le seul truc qui me chiffonne c'est ça, le code de sortie :
    ce matin c'est correct :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	...
            until (not Running) and (Output.NumBytesAvailable = 0);
            ShowMessage(IntToStr(ExitStatus)+' '+IntToStr(BytesRead)); // 0 144
          finally
    	...
    maintenant (144 --> 223 c'est normal, j'ai changé les data à récupérer) c'est bizarre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    	...
            until (not Running) and (Output.NumBytesAvailable = 0);
            ShowMessage(IntToStr(ExitStatus)+' '+IntToStr(BytesRead)); // 512 223
    	// ou
        //  ShowMessage(IntToStr(ExitCode)+' '+IntToStr(BytesRead)); // 2 223 --help: "On error, a nonzero value is returned."
          finally
    	...
    et l'aide me dit, à propos de cet ExitStatus :
    ExitStatus contains the exit status as reported by the OS for the process when it stopped executing: Normally, this is the exit code of the process.
    The value of this property is only meaningful when the process has finished executing. If it is not yet running then the value is -1. (it was zero in earlier versions of FPC)
    Et donc je récupère un 512 alors que echo $? dans une console me dit "0" = tout va bien, donc on ne va pas se prendre la tête sauf si quelqu'un a une solution.

    Merci pour l'idée OutputDebugString mais pas de bol, ce n'est pas dispo sous Linux. Bah...
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  4. #4
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 466
    Points : 4 647
    Points
    4 647
    Par défaut
    Bonjour,

    Doc sur ExitCode vs ExitStatus :

    "ExitCode is the actual exit code of the process. On UNIX, this may differ from the ExitStatus value if the process was terminated by a signal: in that case ExitStatus is the raw exit status as reported by one of the UNIX Wait command, and ExitCode is the exit code reported by the program."

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  5. #5
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 947
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 947
    Points : 15 403
    Points
    15 403
    Par défaut
    Bonjour,

    Merci de participer.

    Tu penses bien que j'ai moi aussi trouvé l'information que tu publies, même si les mots ne sont pas exactement dans le même ordre.

    Et donc, en fin de manip,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ShowMessage(IntToStr(ExitStatus)+' '+IntToStr(BytesRead)); // --> 512 223
    ShowMessage(IntToStr(ExitCode)+ ' '+ IntToStr(BytesRead)); // -->   2 223 -- from Help: On error, a nonzero value is returned.
    le "223" est lié aux données d'une fonte, autres fontes autres valeurs.

    Et maintenant la question qui tue : que signifient 512 et 2 ?
    Et si je rajoute que hier matin j'avais 0 au lieu de 512 pour le ExitStatus, tu comprendras mieux mon malaise...
    In fine, j'ai parfois toujours (j'ai testé sur 25 fontes) ces deux erreurs. Qu'est-ce que ça signifie ? Nobody knows...

    Thanks God, pour le moment, tout fonctionne à peu près bien, malgré ces erreurs, qui n'en sont peut-être pas...
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  6. #6
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 947
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 947
    Points : 15 403
    Points
    15 403
    Par défaut
    Pour ceux qui sont intéressés :

    je me suis affranchi de ces problèmes de données absentes dans les remontées de fpTTF (de FreePascal) d'une manière un peu sordide, mais comme elle est utilisée par les designers de fontes, alors pourquoi pas moi aussi ?

    En examinant le listing des 935 fontes - 17 incorrectes, j'ai pu constater que si certaines affichaient proprement des données utiles, par ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    FileName          /usr/share/fonts/AutresFontes/Machine/geo703bc.ttf
    FamilyName        GeoSlab703 MdCn BT
    HumanFriendlyName Geometric Slabserif 703 Bold Condensed BT
    PostScriptName    GeometricSlab703BT-BoldCond
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    FileName          /usr/share/fonts/AutresFontes/Machine/DOUR65W.TTF
    FamilyName        Dark Courier
    HumanFriendlyName Dark Courier Bold
    PostScriptName    CourierHP-Bold
    d'autres n'en avaient strictement rien à faire, comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    FileName          /usr/share/fonts/AutresFontes/Machine/gtw.ttf
    FamilyName        GNUTypewriter
    HumanFriendlyName GNUTypewriter
    PostScriptName    GNUTypewriter
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    FileName          /usr/share/fonts/AutresFontes/Ornements/wingding.ttf
    FamilyName        wingding
    HumanFriendlyName wingding
    PostScriptName    wingding
    Alors j'ai fait comme eux, comme ça :
    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
    if CacheItem <> nil then begin
      with CacheItem.FontData do begin
        MemoVisu.Lines.Add('FileName          '+ FileName);
        // 3 nouvelles lignes :
        if FamilyName=''        then FamilyName        := ChangeFileExt(ExtractFileName(FileName),'');
        if HumanFriendlyName='' then HumanFriendlyName := ChangeFileExt(ExtractFileName(FileName),'');
        if PostScriptName=''    then PostScriptName    := ChangeFileExt(ExtractFileName(FileName),'');
        MemoVisu.Lines.Add('FamilyName        '+ FamilyName);
        MemoVisu.Lines.Add('HumanFriendlyName '+ HumanFriendlyName);
        MemoVisu.Lines.Add('PostScriptName    '+ PostScriptName);
        // dessous plus utile avec les  3 nouvelles lignes
        //if (FamilyName='') or (HumanFriendlyName='') or (PostScriptName='')
          //then begin ShowMessage('Error with '+FileName); slError.Add(FileName); end;
      end;
      LoadFontData(CacheItem.FileName);
      CacheItem.Free;
    end;
    Et du coup je me retrouve sans erreur avec 935 fontes disponibles au lieu de 918, genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    FileName          /usr/share/fonts/AutresFontes/Machine/Linedraw.ttf
    FamilyName        Linedraw
    HumanFriendlyName Linedraw
    PostScriptName    Linedraw
    qui n'affichait rien sur les lignes 2,3 et 4 jusqu'à hier. Alors bingo !

    Mais ça prend quand même 18 secondes pour afficher 935x4 lignes, avec un sleep à 5 et un refresh d'affichage comme ça : if i mod 20 = 0 then Application.ProcessMessages;.

    Bon, comme il n'est pas prévu de charger les 935 fontes d'un seul coup, on va dire que ça ira bien ainsi.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  7. #7
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 815
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 815
    Points : 13 531
    Points
    13 531
    Par défaut
    ExitCode dépend du script (ou plus généralement de l'exécutable) et donc du développeur. 0 en cas de succès est communément utilisé mais ce n'est pas une règle, robocopy par exemple (oui bon, Windows) retourne 1 après mise à jour (0 si aucune copie) et seuls les codes supérieurs à 7 sont des erreurs "critiques".

    ExitStatus est une spécialité Unix et d'après ce que j'ai pu voir est le résultat d'une fonction d'attente. L'octet de poids fort contient l'éventuelle erreur (512 = bit 9). Dans ton cas et puisque certaines polices ne retournent rien, on pourrait supposer un timeout.

  8. #8
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 947
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 947
    Points : 15 403
    Points
    15 403
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Dans ton cas et puisque certaines polices ne retournent rien, on pourrait supposer un timeout.
    Admettons.
    Je change mon nombre de fontes dans la mainloop (935-->3), les trois premières de ma liste n'ayant jamais eu de problème, comment expliques-tu cet ExitStatus à 512 qui apparait pour chacune ?

    Le pire c'est que hier matin j'avais 0, mais je n'arrive plus à le reproduire...

    Cependant, tu m'as mis la puce à l'oreille alors j'ai revu mon script avec un autre regard il y a 10 minutes, puis j'ai fait un test avec exit 5 en fin de script et dans Lazarus j'ai eu 1280 pour ExitStatus et 5 pour ExitCode, alors j'ai mis exit 0 en fin de script et j'ai eu 0 aux deux Exit dans Lazarus !

    Impec, Andnotor !
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  9. #9
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 815
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 815
    Points : 13 531
    Points
    13 531
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Je change mon nombre de fontes dans la mainloop (935-->3)
    Ce n'est pas le nombre global auquel je pensais mais des tâches en parallèle synchronisées sur un "WaitAll", certaines finissant en timeout (mais encore une fois, ce n'était que supposition).

    Citation Envoyé par Jipété Voir le message
    j'ai fait un test avec exit 5 en fin de script et dans Lazarus j'ai eu 1280 pour ExitStatus
    Il y a donc une redondance de ExitCode dans l'octet de poids fort de ExitStatus (2 shl 8 = 512 et 5 shl 8 = 1280).

  10. #10
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 947
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 947
    Points : 15 403
    Points
    15 403
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Il y a donc une redondance de ExitCode dans l'octet de poids fort de ExitStatus (2 shl 8 = 512 et 5 shl 8 = 1280).
    Je veux bien te croire, mais je n'irai pas mettre mes mains dans /usr/share/fpcsrc/3.2.2/packages/fcl-process/src/process.pp (qui ne fait pourtant que 59 lignes !), je ne saurais pas quoi y faire,

    Si cette redondance n'est pas gênante, ça va rester comme ça. D'accord ?
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

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

Discussions similaires

  1. petit soucis avec mon graveur
    Par Vador dans le forum Périphériques
    Réponses: 8
    Dernier message: 02/11/2005, 14h58
  2. petit soucis avec les listes
    Par Death83 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 03/09/2005, 10h08
  3. Petit souci avec clause where
    Par ybruant dans le forum SQL
    Réponses: 1
    Dernier message: 21/07/2005, 22h10
  4. petit souci avec des variables avec des fonctions psql
    Par dust62 dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 02/04/2005, 13h45
  5. [DEBUTANT] petits soucis avec un prgm de chat
    Par LechucK dans le forum MFC
    Réponses: 8
    Dernier message: 19/01/2004, 16h52

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