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 :

lancer un script en background


Sujet :

Langage Perl

  1. #1
    Membre éclairé
    Inscrit en
    Mars 2005
    Messages
    319
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 319
    Par défaut lancer un script en background
    salut,

    J'ai un script perl qui appel un autre script perl comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ..
    system ('./monscriptappele.pl &');
    ..
    avec cette methode, je peux lancer plusieur fois monscriptappele.pl vu qu'il est en background;

    mais le probleme est que si le script principal plante alors tous les scripts qui sont en background vont planter car ils ont été lancer par le script principal;
    Comment pourrai je proceder pour que les scripts lancer en background(monscriptappele.pl) continu à tourner même si le script principal plante.

    Merci.

  2. #2
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 606
    Par défaut
    Hello,

    juste pour savoir : pourquoi le programme principal est-il susceptible de planter ?

    Est-ce parce qu'à certains endroits, tu stoppes de toi-même le programme par du exit( ) ou du die( ) ou bien le programme est-il buggé ?

  3. #3
    Membre éclairé
    Inscrit en
    Mars 2005
    Messages
    319
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 319
    Par défaut
    il est susceptible de planter pour plusieurs raison,
    si jamais quelqu'un le kill sans faire expres par exemple

  4. #4
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 606
    Par défaut
    Citation Envoyé par Melvine
    si jamais quelqu'un le kill sans faire expres par exemple


    Hum..... Eh bien, il faut espérer que les sous-programmes que tu lances ensuite n'avaient pas besoin d'écrire ou de mettre à jour des données qu'utilise le programme principal, sinon je vois mal comment tu peux bétonner ton histoire.

    Comment quelqu'un peut s'amuser à tuer le processus d'un programme pendant son exécution ? Tu bosses dans une drôle de boite

  5. #5
    Membre éclairé
    Inscrit en
    Mars 2005
    Messages
    319
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 319
    Par défaut
    personne n'est parfait, c'est pour cela qu'on fait des test;
    si tout le monde faisait aussi bien attention que toi , je pense qu'il n' aurai jamais d'accident;
    mais bon c'est pas question de savoir pourquoi le script principal planterai.

    Comment quelqu'un peut s'amuser à tuer le processus d'un programme pendant son exécution ? Tu bosses dans une drôle de boite



    le script principal appel un autre script perl et c'est fini;il n'attends pas que le script enfant lui renvoi quelquechose.

  6. #6
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 606
    Par défaut
    Citation Envoyé par Melvine
    personne n'est parfait, c'est pour cela qu'on fait des test;
    le script principal appel un autre script perl et c'est fini;il n'attends pas que le script enfant lui renvoi quelquechose.
    Si ton script principal n'appelle qu'un seul autre script Perl, fais l'appel en utilisant exec plutôt que system (mais dans ce cas attention : ceci est à faire à la fin de ton script principal, pas n'importe où).

    Si ton script principal appelle plusieurs autres scripts, là c'est différent et je te conseillerai, toujours via exec plutôt que system, de faire comme une sorte de chaînage :

    Script 1 -> exécute en fin de traitement Script 2
    Script 2 -> exécute en fin de traitement Script 3
    Script 3 -> exécute en fin de traitement Script 4

    etc.

  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
    Non, la solution est de détacher les processus enfants, la façon de procéder dépend de ton système bien sûr. Quel est l'OS ?

    --
    Jedaï

  8. #8
    Membre éclairé
    Inscrit en
    Mars 2005
    Messages
    319
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 319
    Par défaut
    je peux pas utiliser exec parceque avec exec une fois lancer le script enfant,celui ci prend la place du pere et donc le pere n 'existe plus;

    donc j'utilise system, mais avec system si le pere meurt le ou les fils meurent aussi;

    une fois le script pere lancer, je veux qu'il continu a tourner donc la solution exec n est pas bonne

  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
    Bon par exemple si tu es sous Linux, voici ce que dis la FAQ :
    >perldoc -q daemon
    Found in C:\Lang\Perl\lib\pod\perlfaq8.pod
    How do I fork a daemon process?
    If by daemon process you mean one that's detached (disassociated from
    its tty), then the following process is reported to work on most Unixish
    systems. Non-Unix users should check their Your_OS::Process module for
    other solutions.

    * Open /dev/tty and use the TIOCNOTTY ioctl on it. See tty for
    details. Or better yet, you can just use the POSIX::setsid()
    function, so you don't have to worry about process groups.

    * Change directory to /

    * Reopen STDIN, STDOUT, and STDERR so they're not connected to the old
    tty.

    * Background yourself like this:

    fork && exit;

    The Proc::Daemon module, available from CPAN, provides a function to
    perform these actions for you.
    En fait pour ce que tu demandes explicitement, POSIX::setsid() suffirait (après un fork, et avant un exec() ), mais il serait sans doute préférable de suivre ces recommandation pour éviter de perturber les utilisateurs.

    --
    Jedaï

  10. #10
    Membre éclairé
    Inscrit en
    Mars 2005
    Messages
    319
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 319
    Par défaut
    j'ai pas trop saisi jedai
    tu veux faire ça comment ?

    moi j'ai tester cela
    mais ça me tue quand même le fils quand je kill le pere
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      nohup perl ./script.pl &

  11. #11
    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 ne sais pas lire l'anglais ? C'est une compétence pratiquement nécessaire pour faire de l'informatique au jour d'aujourd'hui.

    Ce que cette question de la FAQ de Perl explique c'est comment créer un daemon, autrement dit un processus détaché de son terminal (tty) mais également de tout processus père (il est dans un groupe de processus à lui tout seul usuellement).

    Si tu n'as pas compris tout ça, la solution la plus simple pour toi actuellement est sans doute d'utiliser Proc-Daemon pour tout faire pour toi, sinon il faut que tu forkes puis utilise POSIX::setsid() au minimum pour faire ce que tu veux.

    --
    Jedaï

  12. #12
    Membre éclairé
    Inscrit en
    Mars 2005
    Messages
    319
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 319
    Par défaut
    merci;
    je vais me renseigner sur forker un process et utiliser POSIX::setsid()

  13. #13
    Membre éclairé
    Inscrit en
    Mars 2005
    Messages
    319
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 319
    Par défaut
    mon code se presente ainsi,
    cela veux dire que je dois faire un fork juste avant mon system et appeler seulement mon script sans utiliser nohup et &.
    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
     
    my $dbh = DBI->connect("dbi:Oracle:$dbname", $user, $passwd) or 
    die "Database connection not made: $DBI::errstr";
     
    my $req ="select * from param where pm='PLI'";
     
    my $sth=$dbh->prepare($req);
    $sth->execute();
     
    while (my ($a,$b,$c,$d) = $sth->fetchrow_array()) 
    {
    $times = $d;
     
     
     
    my $dossier = $a;
    my $appli=$c;
     
     
    system ('nohup perl ./fact.pl -d '.$dossier.' -c '.$appli.' -b '.$b.' &');
     
    }
     
    $sth -> finish;
     
    $dbh -> disconnect;

  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
    Oui, et utilise exec() plutôt que system(), après avoir utilisé POSIX::setsid() bien sûr.

    --
    Jedaï

  15. #15
    Membre éclairé
    Inscrit en
    Mars 2005
    Messages
    319
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 319
    Par défaut
    en faite je suis super pedu,
    le fork je connais pas trop;
    je lis les doc sur le net, sa permet de creer un nouveau process qui sera dependant du pere;donc sil pere meurs il continu à vivre;
    mais je vois vraiment pas comment l'integrer dans mon code

    j'ai trouver un site ou il en parle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    defined (my $kid = fork) or die "Cannot fork: $!\n";
    if ($kid) {
        # Parent runs this block
    }
    else {
        # Child runs this block
        setsid or die "Can't start a new session: $!";
        # ...
    }
    mais je pije pas trop ou je devrais mettre ça;
    je dois dire je suis perdu la

  16. #16
    Membre éclairé
    Inscrit en
    Mars 2005
    Messages
    319
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 319
    Par défaut
    j'ai essayer cela
    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
    while (my ($a,$b,$c,$d) = $sth->fetchrow_array()) 
    {
    $times = $d;
     
     
     
    my $dossier = $a;
    my $appli=$c;
     
    $pid = fork;
    if ($pid == 0) 
    { 
    exec ('./fact.pl -d '.$dossier.' -c '.$appli.' -b '.$b.' &');
    }
     
    }
    mais quand je tue le pere les fils meurs

  17. #17
    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 pour ça qu'il faut que tu utilises POSIX::setsid() dans le fils ! Là ce que tu as écris c'est presque exactement l'équivalent de system() (tu rajoute un waitpid() dans le père et tu as exactement system() ). As-tu compris comment le fork marchait ou te contentes tu de recopier un truc que tu as lu sur le net ? Je peux expliquer si tu as besoin.

    --
    Jedaï

  18. #18
    Membre éclairé
    Inscrit en
    Mars 2005
    Messages
    319
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 319
    Par défaut
    je veux bien que tu m'explique mais avant je te dit ce que j'ai compris;
    le system en faite il fait un fork, c'est pour cela qu'on utilise l' exec;
    Pour le fork , il va creer un nouveau process qui aura son propre pid et donc qui se sera totalement independant du pere;
    dans la doc il dise que cela permet au processus en cours (donc le pere) de se dupliquer;
    moi ce que je souhaites c'est que le script principale, permet de lancer plusieurs fois le script ./fact.pl , et que le script principale continu a tourner;
    si jamais le script principale plante et s'arrete de tourner,les scripts enfant eux doivent continuer à tourner;
    et donc le fork va permettre de rendre chaque script enfant (./fact.pl ) independant.

    c'est bien cela ?

  19. #19
    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
    Un fork() (ou embranchement en français) permet de dupliquer un processus, le nouveau processus continue à s'exécuter à partir du fork(), mais dans le fils le fork() retourne 0 alors que dans le père il retourne le pid du fils. Cependant le fils n'est absolument pas indépendant du père, il font partie du même groupe de processus et si tu tues le père, le groupe meurt avec lui (et donc le fils aussi).

    Ce que tu dois faire c'est ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    use POSIX ();
     
    while (my ($dossier,$b,$appli,$d) = $sth->fetchrow_array()) { 
      $times = $d;
     
      $pid = fork; 
      if ($pid == 0) { 
        POSIX::setsid();
        exec ('./fact.pl', -d => $dossier, -c => $appli, -b => $b); 
      }
    }
    Ou quelque chose d'approchant.

    --
    Jedaï

  20. #20
    Membre éclairé
    Inscrit en
    Mars 2005
    Messages
    319
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 319
    Par défaut
    en le faisant comme ceci, ça à l'air de fonction, j'ai tester;
    la seule chose que j'ai rajouté c'est le "&" pour le mettre en background;
    j'ai lancer mon script principal, je l'ai killer
    et j'ai fait un ps -ef | grep fact.pl et j'ai bien un ou plusieurs fils qui continu à tourner sachant que le pere est mort.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    use POSIX ();
     
    while (my ($dossier,$b,$appli,$d) = $sth->fetchrow_array()) { 
      $times = $d;
     
      $pid = fork; 
      if ($pid == 0) { 
        POSIX::setsid();
        exec ('./fact.pl -d '.$dossier.' -c '.$appli.' -b '.$b.' &');
      }
    }

Discussions similaires

  1. [Système] Lancer un script Perl
    Par ebaynaud dans le forum API standards et tierces
    Réponses: 2
    Dernier message: 14/10/2004, 15h54
  2. [langage] script en background
    Par Tuxico dans le forum Langage
    Réponses: 5
    Dernier message: 04/10/2004, 20h32
  3. Réponses: 13
    Dernier message: 01/10/2004, 15h03
  4. [web] Lancer un script en arrière plan
    Par gracouille dans le forum Web
    Réponses: 4
    Dernier message: 27/05/2004, 17h37
  5. [web] Lancer un script CGI
    Par Calou20 dans le forum Web
    Réponses: 10
    Dernier message: 01/03/2004, 17h48

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