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

 C Discussion :

lancer un autre programme.


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre extrêmement actif
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Par défaut lancer un autre programme.
    salut:
    j'ai dans un programme qui lit des commands a travers le reseau. et parmis ces commandes il y en a une qui lui demande de lancer une applications en arriere plan
    (je suis sous linux) donc je fait ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if(C_est_la_bonne_commande)
        system("nohup ./foo &");
    ca marche tout cool tout nikel mais voila que quand je demande au serveur de s'arretter il refuse de se relancer en me disant que le port 9076 (qu'il utilise est deja occuppe) Bind error.
    puis apres une petite audit du reseau j'apprend que c'est foo qui utilise le port 9076.
    surpris car foo n'utilse pas le reseau je me rend compte que la fonction system fait un fork donc elle a copier son code et tant que foo ne termine pas je ne peux pas relancer le serveur.

    ma question est existe t-il une autre methode pour lancer un autre programe en arriere plan et fermer mon programme afin que foo se tourne tranquillement et que je puisse relance mon serveur sans encombre?
    Merci

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lilington Voir le message
    salut:
    j'ai dans un programme qui lit des commands a travers le reseau. et parmis ces commandes il y en a une qui lui demande de lancer une applications en arriere plan
    (je suis sous linux) donc je fait ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if(C_est_la_bonne_commande)
        system("nohup ./foo &");
    ca marche tout cool tout nikel mais voila que quand je demande au serveur de s'arretter il refuse de se relancer en me disant que le port 9076 (qu'il utilise est deja occuppe) Bind error.
    puis apres une petite audit du reseau j'apprend que c'est foo qui utilise le port 9076.
    surpris car foo n'utilse pas le reseau je me rend compte que la fonction system fait un fork donc elle a copier son code et tant que foo ne termine pas je ne peux pas relancer le serveur.

    ma question est existe t-il une autre methode pour lancer un autre programe en arriere plan et fermer mon programme afin que foo se tourne tranquillement et que je puisse relance mon serveur sans encombre?
    Merci
    Salut
    Essaye ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if(C_est_la_bonne_commande)
    {
        if (fork() == 0)
            execl("./foo", "foo", NULL);
        // Ici le fils a disparu et le père continue normalement
    }
    Ici c'est toi qui fait le fork() au lieu de demander au système de le faire. Ainsi ton processus se duplique en 2 comme auparavant. Et dans le fils tu lances ton foo
    Toutefois, dans cette démarche, le execl() va remplacer le code d'exécution de ton serveur par le code d'exécution de foo. Ainsi quand foo s'exécutera, le serveur fils aura alors disparu et ne monopolisera plus le port 9076.
    Et dans le père qui se continue normalement ben rien ne change. Il s'arrête sûrement quelques lignes plus bas en ayant libéré ses ressources y compris le port 9076.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre extrêmement actif
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Par défaut
    j'ai efface le message presendent, j'avais pas bien lut avant de poser ma question.
    j'ai une dernier question.
    tu as du remarque que j'utilisait nohup et un & pour m'assurer que meme si le terminal se plantait le programme tounait toujours, est-ce toujours le cas si je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    exec("./foo","foo",arg1,...,NULL);

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lilington Voir le message
    j'ai efface le message presendent, j'avais pas bien lut avant de poser ma question.
    j'ai une dernier question.
    tu as du remarque que j'utilisait nohup et un & pour m'assurer que meme si le terminal se plantait le programme tounait toujours, est-ce toujours le cas si je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    exec("./foo","foo",arg1,...,NULL);
    Je pense qu'il n'y aura pas de pb. En fait, le nohup fonctionne ainsi: lorsque tu lances un programme depuis ton shell, le shell mémorise le processus correspondant.
    Puis si le shell s'arrête, alors il envoie un signal 1 (SIGHUP) à tous les processus... sauf si tu as demandé explicitement un "no hup" => nohup. Dans ce cas, le shell n'envoie pas de signal 1.

    Or ici ce n'est pas un lancement depuis le shell mais une génération de processus fils programmée directement. Or dans ce cas là, le père peut s'arrêter et disparaitre mais n'envoie pas de hup et donc le fils continue. Donc voilà. Mais bon, un simple test le confirmera...

    Accessoirement les arguments de execl() doivent être mis sous forme de string => exec("./foo","foo","arg1",...,NULL);
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre extrêmement actif
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Par défaut
    accessoirement aussi les arguments sont deja des char *.
    sinon dans mon premier test ca marchait mais en production avec un truc etrange.
    voici ce qui se passe.
    le serveur est lancer comme ceci
    puis le terminal est imediatement ferme.
    les fils sont lance depuis une page web. chaque fois que je lance un fils(avec les meme arguments) sont status est non lance,
    et voici ce que me renvois top:
    4905 lilington 16 0 17524 2076 708 R 20.9 0.1 0:30.93 cuno SINA_sports.xml
    4936 lilington 15 0 12736 1176 820 R 0.7 0.0 0:00.10 top -u alain
    3513 lilington 15 0 281m 12m 8072 S 0.0 0.3 0:00.19 php-cgi cuno_cgi.php
    4740 lilington 15 0 10976 604 500 S 0.0 0.0 0:00.00 ./cunoserv
    4748 lilington 18 0 0 0 0 Z 0.0 0.0 0:36.11 [cuno] <defunct>
    4843 lilington 15 0 66048 1496 1080 S 0.0 0.0 0:00.01 /bin/bash
    4931 lilington 25 0 0 0 0 Z 0.0 0.0 0:00.10 [cunoget] <defunct>
    4932 lilington 15 0 0 0 0 Z 0.0 0.0 0:00.07 [cunoget] <defunct>
    4933 lilington 25 0 0 0 0 Z 0.0 0.0 0:00.06 [cunoget] <defunct>
    soit on a ./cunoserv qui est le serveur qui tourne bien, mais les autres sont tous morts.
    le script php-cgi envois des requettes toutes les minutes pour demander le status des fils. le pere et les fils communiques par fichier txt la simple mise a jours du fichier permet de savoir qu'un fils est toujours en vie et ce qu'il est entrain de faire.
    le serveur envois des reponses de ce genre
    [OK] started 2011-08-28 09:53:05 |last sign 2011-08-27 16:46:00 |status running|spiderID 2
    done
    visiblement comme top me l'a dit le fils soit ./cuno SINA_sports.xml tournent bien mais c'est quoi tous les cunoget <defunct>?
    bon j'explique quand meme c'est quoi cunoget.
    j'ai separer en deux programme. soit
    1/cuno qui se contente de chercher des liens utiles a partir d'une url d'entree et quand ca liste est pleine il lance de la meme maniere que tu m'as montree cunoget.
    2/cunoget lit une url puis telecharge le contenu extrait l'info, les photo, retire la pub, blablabla et ecrit un fichier xml qui contient ce qui nous interresse.
    bon je montre comment je lance cunoget:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     LLinks *qq=Ll2;
         while(qq!=NULL)
         {
             cntt(qq->link,opt);
             qq=qq->next;
             glo_tt1=time(NULL);
             if(glo_tt1-glo_tt0>180)
            {
     //          debug_log("Updating status file",NULL,LOG|INFO,LOG_INFO);
                 glo_tt0=glo_tt1;
                 saveStatus(glo_lastdate,opt->site_en,opt->categ_en,opt->channel_id,glo_pid);
             }
         }
         destroyLLinks(&Ll2);
    voici ce que fait cntt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    static void cntt(const char *url,OPT *opt)
     {
         char *md=MDString((char *)url);
         addLink(&link_MD5,md,"3000");
         if(fork()==0)
         {
             execl("./cunoget","cunoget",
                 url,md,opt->data_b,opt->data_e,opt->site_en,
                 opt->categ_en,opt->site,opt->categ,
                 opt->channel_id,opt->keyword_path,glo_dir,
                 opt->site_id,opt->categ_id,glo_lastdate,NULL);
         }
         free(md);
     }
    je mets aussi comment cunoget recois les info a toute fin utile:
    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
    int main(int argc, char **argv)
     {
         if(argc<15)
              return 0;
         KeywordExtraction_Init(argv[10]);
     
         srand((unsigned int)time(NULL));
     
         char loger[8192];
     //  fprintf(stderr,"Fetching %s\n",argv[1]);
         WebPage *wp=getPage(argv[1],argv[14]);
     
         char *md=argv[2];
         char ctrl[8];
         int alternum=rand()%999;
         sprintf(ctrl,"%c%c%c%c%03d",md[31],md[11],md[1],md[7],alternum); 
     
         if(wp==NULL)
         {
             return 0;
         }
         int b=0,e=-1;
     //  releaseWebPage(&wp);return 0;
         b=findStr(wp->html,argv[3],b);
             ...
             ... //bla bla bla
             return 1;
    bon c'est top qui m'embete un peu car les fils ecrivent bien leur fichier chacun et il ferment bien le fichier. mais j'ai l'impression qu'ils ne se terminent pas correctement.

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lilington Voir le message
    accessoirement aussi les arguments sont deja des char *.
    sinon dans mon premier test ca marchait mais en production avec un truc etrange.
    voici ce qui se passe.
    le serveur est lancer comme ceci
    puis le terminal est imediatement ferme.
    les fils sont lance depuis une page web. chaque fois que je lance un fils(avec les meme arguments) sont status est non lance,
    et voici ce que me renvois top:

    soit on a ./cunoserv qui est le serveur qui tourne bien, mais les autres sont tous morts.
    le script php-cgi envois des requettes toutes les minutes pour demander le status des fils. le pere et les fils communiques par fichier txt la simple mise a jours du fichier permet de savoir qu'un fils est toujours en vie et ce qu'il est entrain de faire.
    le serveur envois des reponses de ce genre
    visiblement comme top me l'a dit le fils soit ./cuno SINA_sports.xml tournent bien mais c'est quoi tous les cunoget <defunct>?
    bon j'explique quand meme c'est quoi cunoget.
    j'ai separer en deux programme. soit
    1/cuno qui se contente de chercher des liens utiles a partir d'une url d'entree et quand ca liste est pleine il lance de la meme maniere que tu m'as montree cunoget.
    2/cunoget lit une url puis telecharge le contenu extrait l'info, les photo, retire la pub, blablabla et ecrit un fichier xml qui contient ce qui nous interresse.
    bon je montre comment je lance cunoget:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     LLinks *qq=Ll2;
         while(qq!=NULL)
         {
             cntt(qq->link,opt);
             qq=qq->next;
             glo_tt1=time(NULL);
             if(glo_tt1-glo_tt0>180)
            {
     //          debug_log("Updating status file",NULL,LOG|INFO,LOG_INFO);
                 glo_tt0=glo_tt1;
                 saveStatus(glo_lastdate,opt->site_en,opt->categ_en,opt->channel_id,glo_pid);
             }
         }
         destroyLLinks(&Ll2);
    voici ce que fait cntt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    static void cntt(const char *url,OPT *opt)
     {
         char *md=MDString((char *)url);
         addLink(&link_MD5,md,"3000");
         if(fork()==0)
         {
             execl("./cunoget","cunoget",
                 url,md,opt->data_b,opt->data_e,opt->site_en,
                 opt->categ_en,opt->site,opt->categ,
                 opt->channel_id,opt->keyword_path,glo_dir,
                 opt->site_id,opt->categ_id,glo_lastdate,NULL);
         }
         free(md);
     }
    je mets aussi comment cunoget recois les info a toute fin utile:
    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
    int main(int argc, char **argv)
     {
         if(argc<15)
              return 0;
         KeywordExtraction_Init(argv[10]);
     
         srand((unsigned int)time(NULL));
     
         char loger[8192];
     //  fprintf(stderr,"Fetching %s\n",argv[1]);
         WebPage *wp=getPage(argv[1],argv[14]);
     
         char *md=argv[2];
         char ctrl[8];
         int alternum=rand()%999;
         sprintf(ctrl,"%c%c%c%c%03d",md[31],md[11],md[1],md[7],alternum); 
     
         if(wp==NULL)
         {
             return 0;
         }
         int b=0,e=-1;
     //  releaseWebPage(&wp);return 0;
         b=findStr(wp->html,argv[3],b);
             ...
             ... //bla bla bla
             return 1;
    bon c'est top qui m'embete un peu car les fils ecrivent bien leur fichier chacun et il ferment bien le fichier. mais j'ai l'impression qu'ils ne se terminent pas correctement.
    Bon, d'après ce que je lis, il semble que tout se passe bien au niveau du travail. Tes fils écrivent tout ce qu'il faut quand il faut et font tout ce qu'il y a à faire. Et donc ton seul souci vient du <defunct> qui apparait au ps

    En fait, ce <defunct> provient du fait que le fils est mort sans que son père soit au courant (sur les Unix plus anciens ces programmes s'affichaient sous le vocable "zombis").
    Je suis pas super au courant de la façon dont fonctionne excecl() mais je présuppose que lorsque le code du fils est remplacé par celui de cunoget(), le vrai fils meurt. Sauf que le père qui a lancé le fork() n'est pas au courant. Il lui faut pour cela taper un wait()

    Voici le code que tu peux mettre pour (j'espère) régler le souci
    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
    static void cntt(const char *url,OPT *opt)
     {
         int status;
         char *md=MDString((char *)url);
         addLink(&link_MD5,md,"3000");
         if(fork()==0)
         {
             execl("./cunoget","cunoget",
                 url,md,opt->data_b,opt->data_e,opt->site_en,
                 opt->categ_en,opt->site,opt->categ,
                 opt->channel_id,opt->keyword_path,glo_dir,
                 opt->site_id,opt->categ_id,glo_lastdate,NULL);
         }
         wait(&status);
         free(md);
     }
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

Discussions similaires

  1. [Système] syntaxe pour lancer un autre programme
    Par mioke dans le forum Langage
    Réponses: 3
    Dernier message: 28/05/2008, 11h08
  2. Réponses: 5
    Dernier message: 04/02/2008, 18h13
  3. Lancer un .exe d'un autre programme
    Par diophantes dans le forum C
    Réponses: 3
    Dernier message: 17/04/2007, 09h51
  4. Lancer un .EXE à partir d'un autre programme
    Par Pascal.Alain.B dans le forum Assembleur
    Réponses: 6
    Dernier message: 26/03/2007, 23h53
  5. Lancer l'exécution d'un autre programme
    Par Neitsa dans le forum Linux
    Réponses: 3
    Dernier message: 21/05/2005, 23h39

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