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

Langage Perl Discussion :

Perl et Signaux : Broken Pipe


Sujet :

Langage Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert Avatar de MarneusCalgarXP
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    911
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 911
    Par défaut Perl et Signaux : Broken Pipe
    Bonjour à tous, ca fait un bout de temps que je ne suis pas venu

    J'ai un petit problème de broken pipe, lors de lecture de fichiers zippés. Le broken pipe se produit lorsque je fais un close du descriptor avant d'avoir atteint la fin du fichier. Y a-t-il un moyen pour éviter ce désagrément ?

    ex:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    use strict;
    use warnings;
     
    my $file = '/home/user1/file.gz';
    open(my $input, "zcat -f $file |") or die("impossible d'ouvrir $file en lecture\n");
    while (<$input>) {
       if ( m/^TOTO$/ ) {
            print("TOTO trouvé !\n");
            last; 
       }
    }
     
    close($input); # génère un broken pipe si toto a été trouvé, autrement dit si je n'ai pas lu l'intégralité du flux
    version de Perl utilisée: v5.6.1 sous Linux

    quelqu'un saurait-il comment éviter ce petit désagrément (qui vient pourir les logs bien évidemment, lorsqu'on ouvre 2000 fichiers simultanément, et qu'on a 2000 broken pipe, bien le bonjour pour lire les traces entre 2) ?

    Merci d'avance !

  2. #2
    Membre Expert Avatar de MarneusCalgarXP
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    911
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 911
    Par défaut
    C'est bon, j'ai trouvé une solution, ce n'est pas un problème de signal mais de stderr de zcat. J'ai ajouté l'option -q (pour quiet) au zcat et les warnings ont disparu

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    open(my $input, "zcat -fq $file |") or die("impossible d'ouvrir $file en lecture\n");

  3. #3
    Membre Expert Avatar de MarneusCalgarXP
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    911
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 911
    Par défaut
    EDIT: finalement, j'ai toujours des broken pipe extrait des logs:
    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
     
    zcat: stdout: Broken pipe
     
    zcat: stdout: Broken pipe
     
    zcat: stdout: Broken pipe
     
    zcat: stdout: Broken pipe
     
    zcat: stdout: Broken pipe
     
    zcat: stdout: Broken pipe
     
    zcat: stdout: Broken pipe
     
    zcat: stdout: Broken pipe
     
    zcat: stdout: Broken pipe
     
    zcat: stdout: Broken pipe
     
    zcat: stdout: Broken pipe
     
    zcat: stdout: Broken pipe
     
    zcat: stdout: Broken pipe
     
    zcat: stdout: Broken pipe
     
    zcat: stdout: Broken pipe
     
    zcat: stdout: Broken pipe
     
    zcat: stdout: Broken pipe
     
    zcat: stdout: Broken pipe

  4. #4
    Expert confirmé
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Par défaut
    Tu pourrais peut-être essayer de ne pas passer par le shell, peut-être est-ce le shell qui émet ces avertissements :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    use IO::Pipe;
     
    my $input = IO::Pipe->new();
    $input->reader('zcat', '-fq', $file) or die("impossible d'ouvrir $file en lecture\n");
    --
    Jedaï

  5. #5
    Membre Expert Avatar de MarneusCalgarXP
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    911
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 911
    Par défaut
    ca ne risque pas de ralentir le process ?

  6. #6
    Expert confirmé
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Par défaut
    Citation Envoyé par MarneusCalgarXP
    ca ne risque pas de ralentir le process ?
    Non, c'est le contraire, puisqu'il n'y a plus l'intermédiaire du shell.

    --
    Jedaï

  7. #7
    Expert confirmé
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Par défaut
    Ben change ton code pour lire jusqu'au bout (s'il n'y a pas trop de pénalité en vitesse à toi de tester).
    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
     
    use strict;
    use warnings;
    use IO::Pipe;
     
    my $pipe = IO::Pipe->new();
    my $file = '/home/user1/file.gz';
    my $input = $pipe->reader('zcat', '-fq', $file)
      or die("impossible d'ouvrir $file en lecture\n");
     
    while (<$input>) {
       if ( m/^TOTO$/ ) {
            print("TOTO trouvé !\n");
            local $/;
            <$input>;
            last; 
       }
    }
     
    $input->close();
    --
    Jedaï

  8. #8
    Membre Expert Avatar de MarneusCalgarXP
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    911
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 911
    Par défaut
    J'ai déjà testé, mais le coût est mlaheureusement trop pénalisant.
    (il y a 2000 fichiers ouverts avec une moyenne de 10 Mo par fichier, et nous avons un impératif de temps à respecter )

    J'avais trouvé une autre solution avec un open3 et une redirection du stderr dans /dev/null, il faudra que je teste si ca supporte la charge...

  9. #9
    Expert confirmé
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Par défaut
    Si rediriger stderr règle le problème, alors essaie ceci :

    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
     
    use strict;
    use warnings;
    use IO::Pipe;
     
    my $pipe = IO::Pipe->new();
    my $file = '/home/user1/file.gz';
    my $input = $pipe->reader("zcat -fq $file 2>dev/null")
      or die("impossible d'ouvrir $file en lecture\n");
     
    while (<$input>) {
       if ( m/^TOTO$/ ) {
            print("TOTO trouvé !\n");
            last; 
       }
    }
     
    $input->close();
    --
    Jedaï

  10. #10
    Membre Expert Avatar de MarneusCalgarXP
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    911
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 911
    Par défaut
    testé, l'appli ne lit plus du tout les fichiers...

    EDIT: je dois recommencer le test, j'avais une erreur de syntaxe, j'ai fait un copier coller de ton code, et il y manque le / devant dev/null

  11. #11
    Membre Expert Avatar de MarneusCalgarXP
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    911
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 911
    Par défaut
    Bon, j'ai pu tester en prod la solution avec open3, la solution a été rejetée au bout de 2 minutes : le temps d'ouverture des fichiers est trop long (au bout de 4 minutes il n'y avait pas encore 600 fichiers ouverts, avec les open ou avec les pipe, on ouvre les 2000 fichiers en moins de 30 secondes).

    Pour ceux que ca interresse quand même, voici un exemple de code avec open3 et redirection du stderr dans /dev/null...

    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
    #!/usr/bin/perl
    use strict;
    use warnings;
    use File::Spec;
    use IPC::Open3;
    use Symbol qw(gensym);
     
    my $file = shift(@ARGV);
     
    open(my $DEVNULL, ">", File::Spec->devnull);
    my $pid = open3(gensym, my $input, $DEVNULL, "zcat -f $file") or die("not opened");
    while( <$input> ) {
        if ( m/TOTO/ ) {
            print "TOTO trouvé !\n";
            last;
        }
    }
    close($input);
    waitpid($pid, 0);

  12. #12
    Membre Expert Avatar de MarneusCalgarXP
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    911
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 911
    Par défaut
    J'ai testé avec le 2>/dev/null, c'est encore pire, ca ouvre un shell par fichier...

    extrait des process sans la redirection dans /dev/null

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    22570 pts/2    SN     0:00  \_ zcat -fq /ARCHIVE/logsByAffiliates/01/23/mwinf2314/postfix/maillog.20070712.132314.gz
    22571 pts/2    SN     0:00  \_ zcat -fq /ARCHIVE/logsByAffiliates/01/2f/mwinf2f18/postfix/maillog.20070712.141922.gz
    22572 pts/2    SN     0:00  \_ zcat -fq /ARCHIVE/logsByAffiliates/01/28/mwinf2819/postfix/maillog.20070712.140140.gz
    22573 pts/2    SN     0:00  \_ zcat -fq /ARCHIVE/logsByAffiliates/01/2a/mwinf2a04/postfix/maillog.20070712.133941.gz
    22574 pts/2    SN     0:00  \_ zcat -fq /ARCHIVE/logsByAffiliates/01/28/mwinf2829/postfix/maillog.20070712.130312.gz
    22575 pts/2    SN     0:00  \_ zcat -fq /ARCHIVE/logsByAffiliates/01/21/mwinf2107/postfix/maillog.20070712.134015.gz
    22576 pts/2    SN     0:00  \_ zcat -fq /ARCHIVE/logsByAffiliates/01/27/mwinf2705/postfix/maillog.20070712.142221.gz
    22577 pts/2    SN     0:00  \_ zcat -fq /ARCHIVE/logsByAffiliates/01/2f/mwinf2f11/postfix/maillog.20070712.135918.gz
    22578 pts/2    SN     0:00  \_ zcat -fq /ARCHIVE/logsByAffiliates/01/20/mwinf2028/postfix/maillog.20070712.134356.gz
    22579 pts/2    SN     0:00  \_ zcat -fq /ARCHIVE/logsByAffiliates/01/27/mwinf2707/postfix/maillog.20070712.131937.gz
    22580 pts/2    SN     0:00  \_ zcat -fq /ARCHIVE/logsByAffiliates/01/23/mwinf2321/postfix/maillog.20070712.132046.gz
    22581 pts/2    SN     0:00  \_ zcat -fq /ARCHIVE/logsByAffiliates/01/24/mwinf2432/postfix/maillog.20070712.142303.gz
    extrait des process avec la redirection dans /dev/null

    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
     
    18326 pts/2    SN     0:00  \_ sh -c zcat -fq /ARCHIVE/logsByAffiliates/01/23/mwinf2333/postfix/maillog.20070712.130359.gz 2>/dev/null
    18330 pts/2    SN     0:00  |   \_ zcat -fq /ARCHIVE/logsByAffiliates/01/23/mwinf2333/postfix/maillog.20070712.130359.gz
    18340 pts/2    SN     0:00  \_ sh -c zcat -fq /ARCHIVE/logsByAffiliates/01/25/mwinf2505/postfix/maillog.20070712.142151.gz 2>/dev/null
    18345 pts/2    SN     0:00  |   \_ zcat -fq /ARCHIVE/logsByAffiliates/01/25/mwinf2505/postfix/maillog.20070712.142151.gz
    18342 pts/2    SN     0:00  \_ sh -c zcat -fq /ARCHIVE/logsByAffiliates/01/2e/mwinf2e15/postfix/maillog.20070712.135905.gz 2>/dev/null
    18344 pts/2    SN     0:00  |   \_ zcat -fq /ARCHIVE/logsByAffiliates/01/2e/mwinf2e15/postfix/maillog.20070712.135905.gz
    18343 pts/2    SN     0:00  \_ sh -c zcat -fq /ARCHIVE/logsByAffiliates/01/2a/mwinf2a21/postfix/maillog.20070712.130359.gz 2>/dev/null
    18346 pts/2    SN     0:00  |   \_ zcat -fq /ARCHIVE/logsByAffiliates/01/2a/mwinf2a21/postfix/maillog.20070712.130359.gz
    18348 pts/2    SN     0:00  \_ sh -c zcat -fq /ARCHIVE/logsByAffiliates/01/24/mwinf2429/postfix/maillog.20070712.132312.gz 2>/dev/null
    18351 pts/2    DN     0:00  |   \_ zcat -fq /ARCHIVE/logsByAffiliates/01/24/mwinf2429/postfix/maillog.20070712.132312.gz
    18349 pts/2    SN     0:00  \_ sh -c zcat -fq /ARCHIVE/logsByAffiliates/01/25/mwinf2508/postfix/maillog.20070712.142238.gz 2>/dev/null
    18352 pts/2    RN     0:00  |   \_ zcat -fq /ARCHIVE/logsByAffiliates/01/25/mwinf2508/postfix/maillog.20070712.142238.gz
    18350 pts/2    SN     0:00  \_ sh -c zcat -fq /ARCHIVE/logsByAffiliates/01/23/mwinf2313/postfix/maillog.20070712.142349.gz 2>/dev/null
    18353 pts/2    RN     0:00      \_ zcat -fq /ARCHIVE/logsByAffiliates/01/23/mwinf2313/postfix/maillog.20070712.142349.gz

  13. #13
    Membre Expert Avatar de MarneusCalgarXP
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    911
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 911
    Par défaut
    autre problème avec l'utilisation des IO :: Pipe : les process ne sont jamais libérés, or mon application est un démon, et pour cette nuit, 14 000 process zombies ont été générés

    je vais retourner au vieux open classique, tant pis...

  14. #14
    Expert confirmé
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Par défaut
    C'est parce que tu gardes une référence sur tes objets IO::Pipe, sinon ils sont automatiquement détruits et le processus zombie éliminé dès que la dernière référence à l'objet IO::Pipe disparait. Tu devrais toujours essayer de limiter au maximum la portée de tes variables, mais avec un daemon, ce conseil est dix fois plus important encore !!

    --
    Jedaï

  15. #15
    Membre Expert Avatar de MarneusCalgarXP
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    911
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 911
    Par défaut
    Effectivement, je garde des références globales sur chaque fichier tant qu'il n'a pas été parsé intégralement, mais une fois qu'il est terminé, je libère bien le process et je vide les référence (delete dans la hash qui référence les flux), mais il restent tout de même en mémoire... (dans le cadre des open, les zcat sont bien libérés à la fin)

  16. #16
    Expert confirmé
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Par défaut
    Appelle tu bien close() ? Il y a un bug dans IO::Pipe : DESTROY n'appelle pas close(), ce comportement hérité de IO::Handle est raisonnable pour celui-ci (car les handles sur lesquelles on n'a plus de référence sont automatiquement détruits), mais pas pour IO::Pipe puisque son close() appelle waitpid()... Je rapporte le bug et propose un patch, ça devrait être corrigé rapidement je pense (mais ça ne t'aidera pas sauf si tu mets à jour tes modules).

    --
    Jedaï

  17. #17
    Membre Expert Avatar de MarneusCalgarXP
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    911
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 911
    Par défaut
    J'ai uniquement fait des close, pas des destroy...

Discussions similaires

  1. Exception Broken pipe
    Par yarf dans le forum Entrée/Sortie
    Réponses: 7
    Dernier message: 08/04/2020, 17h54
  2. [JDBC] Erreur java.sql.SQLException: Io exception: Broken pipe pool tomcat
    Par lbd_9C dans le forum Interfaces de programmation
    Réponses: 0
    Dernier message: 29/05/2008, 18h00
  3. Broken Pipe sur un envoi de mail
    Par El_touristo dans le forum Langage
    Réponses: 1
    Dernier message: 25/10/2007, 16h04
  4. Broken Pipe & Sockets
    Par |PaRa-BoL dans le forum POSIX
    Réponses: 5
    Dernier message: 18/01/2007, 10h04
  5. Erreur Broken Pipe + Mysql + Tomcat
    Par akademiks dans le forum Hibernate
    Réponses: 1
    Dernier message: 04/09/2006, 16h33

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