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 :

Boucle infinie stoppable


Sujet :

Langage Perl

  1. #21
    Futur Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2006
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 29
    Points : 9
    Points
    9
    Par défaut
    C'est dans le cadre du travail, on a des bases de données sur différents serveurs et nous devons depuis une machine lire de façon constante ces bases et traiter ce qu'on y lit. Je ne peux pas installer ce programme sur chaque serveur, je dois attaquer ces serveurs depuis une machine. Tout fonctionne bien, j'arrive à lire les bases et à tout traiter etc... je n'arrive simplement pas à agir sur ces threads.

  2. #22
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    Je me doute bien que c'est dans le cadre du travail. Tu n'as pas de serveurs de BD chez toi, quoique, chacun ses passions .

    Tu as donc un programme qui tourne sur un serveur à l'infini. Sauf que ce que je ne comprends pas, tu lances trois threads et souhaite lancer une action qui s'effectue sur les trois, quel intérêt des threads ?

  3. #23
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    Tu peux faire tout ça sans passer par des threads.

  4. #24
    Futur Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2006
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 29
    Points : 9
    Points
    9
    Par défaut
    Pas forcémment, je peux très bien lancer une action sur un seul des threads. Par exemple je peux demander d’arrêter de lire sur la base X donc je dit au thread qui lit la base X de stopper.
    J'ai fait les threads car je veux notamment que la lecture sur chacun des serveurs de BDD se fasse en parallèle.

    Mais si tu as d'autres idées je suis preneur ! Dans tous les cas j'aimerais vraiment me sortir de ce souci de variables partagées entre un programme principal et ses threads

  5. #25
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    Tant que tu ne lances aucune action sur une base, rien ne se passe. Dans ce cas, le thread ne sert à rien.
    Moi je vais du principe qu'il faut toujours aller au plus simple.

    Moi je ferai un programme principal en écoute. Si tu lui dit Action1 serveurA, il lance une tâche sur le serveur A, voir même, il lance un thread à ce moment qui sera détruit à la fin de la tâche. Puis ton prog, reste en écoute d'autres demandes.

  6. #26
    Futur Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2006
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 29
    Points : 9
    Points
    9
    Par défaut
    Comme je te l'ai dit, je dois toujours être en lecture sur les tables car elles sont alimentés par d'autres programmes et suivant ce que je lis je dois faire des trucs.
    Donc oui j'ai un programme principal en écoute des actions à effectuer mais à coté de ça je lis des bases sur plusieurs serveurs, en parallèle et de façon constante.

    Est-ce que tu vois ce qui ne va pas dans le code que je copié collé tout à l'heure ?

  7. #27
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    Il faut tout reprendre à zéro et revoir quoi partager.

  8. #28
    Futur Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2006
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 29
    Points : 9
    Points
    9
    Par défaut
    C'est à dire ? ><
    Je sais très bien ce que je veux partager : une tableau par "action", qui sera alimenté par mon programme principal avec les numéros de thread, comme ça chaque thread sait ce qu'il doit faire..

  9. #29
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    que veux tu partager concrètement avec tes threads, quel type d'info, t'as des exemples ?

  10. #30
    Futur Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2006
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 29
    Points : 9
    Points
    9
    Par défaut
    Et bien leur dire de se stopper, de se mettre en pause, d'envoyer des informations sur ce qu'ils ont fait, etc...
    En somme j'aimerais communiquer avec mes threads.
    Alors pour les mettre en pause ou les stopper j'avais eu l'idée de changer un attribut des objets threadés, on en revient à mon premier post : comment changer un attribut d'un objet threadé depuis le programme principal ?

  11. #31
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    Vive les threads, c'est casse-tête .

    Je vais fouiller des vieilles doc ou code que j'avais fait sur ce sujet.

  12. #32
    Futur Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2006
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 29
    Points : 9
    Points
    9
    Par défaut
    Carrément
    Franchement, je peux comprendre que je suis peut être parti sur une piste pas géniale, mais je suis sûr que l'on peut faire marcher le code que j'ai copié collé tout à l'heure, il doit bien y avoir un moyen...

  13. #33
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    Bon bah le partage ne fonctionne pas comme j'ai eu l'habitude de faire. C'est surement dû au fait que l'écoute fork une fois de plus le programme principal.

  14. #34
    Futur Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2006
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 29
    Points : 9
    Points
    9
    Par défaut
    Ta phrase ma mis la puce à l'oreille !
    J'ai remplacé le module Net::Server::Prefork que l'on m'avait innocemment conseillé par Net::Server et cela semble tourner mieux !! ;) (même si j'ai effectivement besoin des options Net::Server::Prefork... mais bon si ça marche je peux oublier ça)

    Seul bizarrerie, le code sensé être exécuté après la boucle infinie ne l'est pas...

    main.pl :
    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
     
    #!/usr/bin/perl
     
    use strict; use warnings;
    use TestServer;
     
    my $iPid = fork();
    if($iPid == 0)
    {
    	my $oServer = new TestServer();
    	$oServer->Start() if $oServer;
    }elsif(defined $iPid)
    {
    	exit 0;
    }else
    {
    	die("Process error.\n")
    }


    TestServer.pm :
    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
     
    #!/usr/bin/perl
     
    use strict; use warnings;
    use Net::Server;
    use threads;
    use threads::shared;
     
    use TestThread;
    package TestServer;
    our @ISA = qw(Net::Server);
     
    sub new
    {
        my $sClass = $_[0];
        my $this = {};
        $this->{aThreads} = ();
        bless($this, $sClass);
        return($this);
    }
     
    our @aStoppedThreads :shared;
     
    sub Start
    {
    	my $this = shift;
    	for(my $i = 1; $i <= 3; $i++)
    	{
    		my $oThread = new TestThread($i, \@aStoppedThreads);
    		if($oThread)
    		{
    			push(@{$this->{aThreads}}, $oThread);
    			my $tr = threads->new(
    			 sub
    			 {
    				$oThread->Process()
    			 }
    			);
    			$tr->detach();
    		}
    	}
     
    	sub process_request 
    	{
    		my $this = shift;
    		eval 
    		{
    		  local $SIG{'ALRM'} = sub 
    		  { 
    			die "Timed Out!\n" 
    		  };
    		  my $timeout = 1;
     
    		  my $previous_alarm = alarm($timeout);
    		  while(<STDIN>) 
    		  {
    			s/\r?\n$//;
    			$this->_ProcessCommand($_);
    			alarm($timeout);
    			last if /quit/i;
    		  }
    		  alarm($previous_alarm);
    		};
     
    		if($@ =~ /timed out/i)
    		{
    			print STDOUT "Timed Out.\r\n";
    			return;
    		}
    	}
    	$this->run(
    	  port => 20203
    	);
    }
     
    sub _ProcessCommand
    {
      my ($this, $sCommand) = @_;
      if($sCommand eq "stop")
      {
      	$this->Stop()
      }
    }
     
    sub Stop()
    {
    	print "Stopping...\n";
        my $this = shift;
     
    	foreach my $oThread (@{$this->{aThreads}})
    	{
    		push(@aStoppedThreads, $oThread->{index});
    		print STDOUT $oThread->{index} . " ajout au stop \n";
    		$oThread->Stop();
    	}
    	share(@aStoppedThreads);
    }
     
    return(1);

    TestThread.pm:
    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
    39
     
    #!/usr/bin/perl
     
    use strict; use warnings;
    use Data::Dumper;
    package TestThread;
     
    sub new
    {
    	my $sClass = $_[0];
        my $this = {};
        $this->{index} = $_[1];
    	$this->{aStopped} = $_[2];
        bless($this, $sClass);
        return($this);
    }
     
    sub Process
    {
    	my $this = shift;
    	my $iIndex = $this->{index};
    	my @aStopped = @{$this->{aStopped}};
     
    	print STDOUT "Thread $iIndex starting...\n";
    	until($this->{index} ~~ @aStopped)
    	{
    		print STDOUT "$iIndex Running...\n";
    		sleep(2);
    	}
    	print STDOUT "$iIndex stopped\n"; # !!!! N'EST PAS EXECUTE
    }
     
    sub Stop()
    {
    	my $this = shift;
    	print STDOUT $this->{index} . " stop recu\n";
    }
     
    return(1);

  15. #35
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    Je vais tester ça chez moi, néanmoins, j'ai trouvé une autre solution en passant par un fichier au lieu de passer par des variables partagées.

  16. #36
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    voilà le prog

    ecoute.pl
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/usr/bin/perl
    use Carp;
    use strict;
    use warnings;
    use TestServer;
     
    my $objet_test = TestServer->new( 'nb' => 3, );
    $objet_test->commencer();
     
    __END__
    TestServer.pm
    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    package TestServer;
     
    use strict;
    use warnings;
    use base qw(Net::Server::PreFork);    # any personality will do
    use threads;
    use threads::shared;
     
    my %threads_lances;
    my $compteur_thread = 0;
    our $test : shared;
    $test = 1;
     
    sub new {
      my ( $class, %info ) = @_;
     
      my $this = {};
      bless( $this, $class );
     
      $this->{NombreThreads} = $info{nb};
      $this->{MesThreads}    = [];
     
      return ($this);
    }
     
    sub commencer {
      my ($this) = @_;
     
      # Lancement des threads
      if ( exists $this->{NombreThreads} ) {
        print "Lancement de $this->{NombreThreads} threads...\n";
        for ( 1 .. $this->{NombreThreads} ) {
          $compteur_thread++;
          my $thread = threads->create( \&process, $compteur_thread );
          $threads_lances{$compteur_thread} = $thread;
          $thread->detach;
        }
      }
     
      # Lancement du processus d'écoute
      TestServer->run();
     
      return;
    }
     
    sub process {
      my ($num_thread) = @_;
     
      print "Lancement du thread $num_thread\n";
      while (1) {
        print "\tThread $num_thread en cours...\n";
        my $fichier = $num_thread . '.txt';
        open FH, '<', $fichier or sleep 2, next;
        my $action = <FH>;
        close FH;
        unlink $fichier;
        print "THREAD $num_thread : Action : $action\n";
        sleep 2;
      }
      return;
    }
     
    sub process_request {
      my $this = shift;
     
      eval {
     
        local $SIG{'ALRM'} = sub { die "Timed Out!\n" };
        my $timeout = 30;    # give the user 30 seconds to type some lines
     
        my $previous_alarm = alarm($timeout);
        while (<STDIN>) {
          s/\r?\n$//;
          #print "You said '$_'\r\n";
          alarm($timeout);
          last if /quit/i;
     
          # action de type NUM:ACTION
          if (/(\d+):(\w+)/i) {
            $this->commande( $1, $2 );
          }
        }
        alarm($previous_alarm);
     
      };
     
      if ( $@ =~ /timed out/i ) {
        print STDOUT "Timed Out.\r\n";
        return;
      }
      exit;
      return;
    }
     
    sub commande {
      my ( $this, $num, $action ) = @_;
     
      # Création du fichier $num.txt et ecrivons l'action
      my $fichier = $num . '.txt';
      open FH, '>', $fichier or die("Impossible de créer $fichier\n");
      print FH $action;
      close FH;
      return;
    }
     
    1;
    __END__
    Pour donner une action tu tapes
    1:TON ACTION ou 2:TON ACTION ou 3:TON ACTION

  17. #37
    Futur Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2006
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 29
    Points : 9
    Points
    9
    Par défaut
    OK je teste ça, même si je t'avoues que de passer par des fichiers ne me semble pas optimal, je me trompe ?

    Remarque par rapport à mon code de tout à l'heure, en fait si le bout de code après ma boucle n'est pas exécute ce n'est pas parce que la boucle s'est terminé mais parce que l'appel au serveur semble tout couper brutalement après le stop.. bref merci je te tiens au courant

  18. #38
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    Citation Envoyé par snakepierre Voir le message
    OK je teste ça, même si je t'avoues que de passer par des fichiers ne me semble pas optimal, je me trompe ?
    Bien implémenté, c'est aussi optimal.

  19. #39
    Futur Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2006
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 29
    Points : 9
    Points
    9
    Par défaut
    Merci beaucoup, ça tourne très bien avec cette solution

  20. #40
    Futur Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2006
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 29
    Points : 9
    Points
    9
    Par défaut
    Hello,

    Juste pour dire que j'ai fini par trouver un module sympa IPC::ShareLite qui permet de faire de la mémoire partagée, c'est plus pratique

    Merci a+

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 3 PremièrePremière 123 DernièreDernière

Discussions similaires

  1. [Boucle Infinie] pour un menu
    Par NhyMbuS dans le forum C++
    Réponses: 5
    Dernier message: 20/07/2005, 09h14
  2. symptome de la boucle infinie dans une requete
    Par ouam81 dans le forum Langage SQL
    Réponses: 8
    Dernier message: 27/05/2005, 12h10
  3. Réponses: 15
    Dernier message: 24/05/2005, 08h34
  4. [Socket] Pb de boucle infinie
    Par Myogtha dans le forum Entrée/Sortie
    Réponses: 12
    Dernier message: 10/06/2004, 14h10
  5. [C#] Comment eviter les boucles infinies ?
    Par Thomas Lebrun dans le forum C#
    Réponses: 12
    Dernier message: 09/06/2004, 00h04

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