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 :

threads et variables partagées


Sujet :

Langage Perl

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 5
    Points : 3
    Points
    3
    Par défaut threads et variables partagées
    Bonjour,
    J'essaie de capturer le signal SIGINT pour quitter proprement mon script perl qui fait tourner une Thread. Mais voilà le problème, J'aimerais que mon thread finisse ce qu'il a à faire et rende la main au script perl principal avant que que ce dernier ne quitte aussi. L'exemple qui suit ne fait rien de particulier. Le thread affiche une chaine de caractère jusqu'à ce que la variable partagée soit modifiée. Ensuite c'est le script perl principal qui s'arrête.
    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
     
    #! /usr/bin/perl
    use threads;
    use threads::shared;
     
    my $flag : shared = 0;
    $thr1 = threads->new(sub {
        lock($flag);
        while (!$flag) {
            print "thread\n";
            sleep(3);
            lock($flag);
        }
    });
    $SIG{INT} = sub {
        $thr2 = threads->new(sub {
            lock($flag);
            $flag = 1;
        });
        $thr2->join;
        $thr1->join;
        exit;
    };
    $thr1->join;
    (Je ne sais pas s'il est nécessaire de faire un "lock" pour les accès en lecture sur une variable partagée dans un thread)
    Dans le raisonnement, le script perl ne devrait pas quitter sans que le thread soit terminé. Dans mon code c'est autre chose :s
    Je lance le script, "thread" est affiché en boucle, mais je n'arrive pas à quitter proprement avec la commande "ctrl+c", la boucle ne se termine pas (mon OS : SLES 10, juste au cas où ).
    Auriez-vous des idées?
    Merci.
    --
    Mr_Brown

  2. #2
    Expert éminent
    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
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par Mr_Brown
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #! /usr/bin/perl
    use threads;
    use threads::shared;
     
    my $flag : shared = 0;
    $thr1 = threads->new(sub {
        lock($flag);
        while (!$flag) {
            print "thread\n";
            sleep(3);
            lock($flag);
        }
    });
    Regarde ton premier lock(), il est dans la portée de la sub, donc il ne se "unlock" qu'en sortant de la sub, autrement dit $flag est locké dès l'entrée dans la sub() et reste locké, donc personne ne peut la modifier, et ainsi la boucle est sans fin...
    Ce que tu veux faire, c'est plutôt :
    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
    #! /usr/bin/perl
    use threads;
    use threads::shared;
     
    my $flag : shared = 0;
    $thr1 = threads->new(sub {
      while (1) {
      { 
        lock($flag);
        unless( $flag ) {
          print "thread\n";
          return;
        }
      }
        sleep(3);
      }
    });
    Mais tu peux faire ça bien plus proprement et efficacement avec un cond_wait() et un cond_broadcast() :
    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
    #! /usr/bin/perl
    use threads;
    use threads::shared;
     
    my $flag : shared = 0;
    $thr1 = threads->new(sub {
      lock($flag);
      cond_wait( $flag ) until $flag;
      print "thread\n";
    });
    $SIG{INT} = sub {
      $thr2 = threads->new(sub {
        lock($flag);
        $flag = 1;
        cond_broadcast($flag);
      });
      $thr2->join;
      $thr1->join;
      exit;
    };
    $thr1->join;
    --
    Jedaï

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Merci pour ta réponse!
    Mais ça ne fonctionne toujours pas, je n'arrive pas à sortir de ma boucle. :s Sinon, juste pour précision, je veux que mon thread $thr1 s'arrete sur le changement de valeur de la variable $flag.
    Citation Envoyé par Jedai
    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
    #! /usr/bin/perl
    use threads;
    use threads::shared;
     
    my $flag : shared = 0;
    $thr1 = threads->new(sub {
      lock($flag);
      cond_wait( $flag ) until $flag;
      print "thread\n";
    });
    $SIG{INT} = sub {
      $thr2 = threads->new(sub {
        lock($flag);
        $flag = 1;
        cond_broadcast($flag);
      });
      $thr2->join;
      $thr1->join;
      exit;
    };
    $thr1->join;
    --
    Jedaï
    Donc ici, il vaut mieux l'initialiser à 1 et le modifier à 0 dans le deuxième thread $thr2, non?

  4. #4
    Expert éminent
    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
    Points : 8 586
    Points
    8 586
    Par défaut
    Je crois que mon code est correct, d'ailleurs ceci fonctionne :
    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
    #! /usr/bin/perl
    use strict; use warnings;
     
    use threads;
    use threads::shared;
     
    my $flag : shared = 0;
    my $thr1 = threads->create(sub {
      lock($flag);
      print "hello !\n";
      cond_wait( $flag ) until $flag;
      print "thread\n";
    });
     
    my $thr2 = threads->create(sub {
        lock($flag);
        $flag = 1;
        cond_signal($flag);
    });
     
    $thr2->detach;
    $thr1->join;
     
    __END__
    Malheureusement, mêler les signaux et les threads semble donner des résultats très mitigé. Je te recommande d'abandonner cette conception...
    Si tu nous dis ce que tu veux faire, nous pourrons peut-être te suggérer des alternatives.

    --
    Jedaï

Discussions similaires

  1. thread - variable partagée non souhaitée
    Par silenteagle dans le forum C
    Réponses: 11
    Dernier message: 25/07/2013, 17h44
  2. Problème de variable partagée
    Par nicolas66 dans le forum Réseau
    Réponses: 9
    Dernier message: 16/06/2006, 14h35
  3. [debutant]threads - variables partagées.
    Par nivose110 dans le forum Concurrence et multi-thread
    Réponses: 1
    Dernier message: 18/01/2006, 06h34
  4. threads et variables communes
    Par buzzz dans le forum Windows
    Réponses: 3
    Dernier message: 21/02/2005, 13h39
  5. [CR] Variables partagées
    Par titdiable dans le forum SAP Crystal Reports
    Réponses: 6
    Dernier message: 21/12/2004, 09h16

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