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 process totalement indépendant


Sujet :

C++

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    244
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 244
    Points : 159
    Points
    159
    Par défaut Lancer un process totalement indépendant
    Bonjour,

    Je débute en C++ et j'ai une petite question!
    Dans mon programme, je suis amené a faire un system("/etc/init.d/httpd restart"); (pas sécure je sais ^^) mais via ce système ce qui m'embête c'est que httpd "dépend" donc de mon programme C++. Si je stop mon programme, httpd continue à tourner mais cela ne libere pas les ports utilisés par mon programme de base.

    Je pense donc que httpd est lancé en tant que fils de mon programme.

    Y a t'il une solution, a part QProcess, pour lancer un programme totalement indépendant ?

    Excusez moi si je n'ai pas été super clair.

    Merci d'avance
    L'informatique au service de l'écologie avec ecomail.fr - Mon hébergeur : Microheb

  2. #2
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Au niveau C-pure bas niveau tu as fork. Je serai surpris si boost ou Poco ne proposait pas une abstraction haut niveau.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  3. #3
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 156
    Points
    3 156
    Par défaut
    Hello

    fork est de l'UNIX, il est pas disponible sur windows, sur lequel il faut utiliser CreateProcess. Ces fonctions ne font pas partie du standard, d'où la divergence sur ces deux plateformes.

    Je pense que ceci devrait fortement t'intéresser.
    Find me on github

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    244
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 244
    Points : 159
    Points
    159
    Par défaut
    Merci pour vos réponses.

    Je vais essayer de voir du coté de fork!
    L'informatique au service de l'écologie avec ecomail.fr - Mon hébergeur : Microheb

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    244
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 244
    Points : 159
    Points
    159
    Par défaut
    D'après ce que je vois sur fork, le processus "pere" reste dépendant du fils non ?

    Donc si dans le processus fils je lance un system("/etc/init.d/httpd restart"), le fils ne sera t-il pas le pere de httpd ? Et dans ce cas, le fils ne se terminera jamais et donc (si je comprend bien), le père non plus.

    Ensuite j'ai vu que exec() remplace le processus par un nouveau processus. Mais est ce que ce nouveau processus sera toujours fils du processus pere qui a fork ?
    L'informatique au service de l'écologie avec ecomail.fr - Mon hébergeur : Microheb

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Bonsoir,

    Citation Envoyé par furtif1 Voir le message
    Je débute en C++ et j'ai une petite question!
    Dans mon programme, je suis amené a faire un system("/etc/init.d/httpd restart"); (pas sécure je sais ^^) mais via ce système ce qui m'embête c'est que httpd "dépend" donc de mon programme C++.
    Non. Les scripts de init.d sont faits pour lancer en tâche de fond les différents « services » correspondant au runlevel dans lequel tu te trouves. Tout ce qui sera lancé à cette occasion sera complètement indépendant de ton programme, et heureusement parce qu'autrement, ta commande system() ne te rendrait pas la main.

    Si je stop mon programme, httpd continue à tourner mais cela ne libere pas les ports utilisés par mon programme de base. Je pense donc que httpd est lancé en tant que fils de mon programme.
    En principe, ça n'a rien à voir. Je pencherais plus, à première vue, pour un gag du style SO_REUSEADDR ou autre. Mais comme on n'a pas encore vu la première ligne de ton programme…

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    244
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 244
    Points : 159
    Points
    159
    Par défaut
    Merci pour ta réponse.

    Je ne sais pas ce que je peux te mettre comme ligne qui soit significative.

    Pour être plus précis. J'ai lancé mon programme sur le port 9990. Jusque la, pas de soucis.

    Depuis une interface web, je me connecte a mon programme en socket et je lui demande de faire un reboot de apache (httpd). Le programme fait ce qu'on lui demande. Avec la fonction system() et j'ai ajouté un fork() et ce qu'il faut pour que la commande soit bien lancé dans le fils créé par le fork.

    Jusque la, toujours ok.

    Maintenant je poweroff mon programme. Il se termine (ou je le kill). Mais lorsque je fais un netstat -anp | grep 9990 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    netstat -anp | grep 9990
    tcp        0      0 0.0.0.0:9990                0.0.0.0:*                   LISTEN      15744/httpd
    Il semblerait donc que httpd bloque le port 9990. Qui est je le rappel le port d'écoute du serveur en C.

    En espérant avoir donner un peu plus d'informations utile.

    Merci d'avance
    L'informatique au service de l'écologie avec ecomail.fr - Mon hébergeur : Microheb

  8. #8
    Membre régulier
    Inscrit en
    Avril 2008
    Messages
    95
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 95
    Points : 110
    Points
    110
    Par défaut
    Bonjour,

    D'accord avec Obsidian: ton programme n'aura pas la main sur httpd juste parce qu'il demande le restart. Pour info (même si je ne suis pas allé voir directement dans le code de httpd), les damone font un fork en interne de leur code, justement pour être des daemon, donc je ne comprend pas trop le besoin de fork que tu dois faire au sein de ton programme.

    Pour ce qui est du port 9990, il me semble que si ton programme ne le ferme pas correctement quand il se termine ou quand tu le kill, et bien httpd ne saura pas que ton programme n'est plus là s'il n'est pas amené à communiquer de nouveau avec lui. En effet après la mort de ton programme, si httpd devait envoyer quelquechose sur la socket il recevrait le signal SIG_PIPE et fermerait probablement le port pour cause d'erreur.
    Concrètement, fermes-tu le port du coté de ton programme lorsqu'il se termine?

    A+
    manpe

  9. #9
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Ok, j'ai fini par comprendre. Ton socket est en soi un descripteur de fichier et, à ce titre, il est par défaut hérité par tous tes processus fils. Même dans le cas de system(), cette fonction forke et fait un execv() sur le shell en usage, lequel shell hérite donc du descripteur sans le savoir, et ce shell lance implicitement des sous-shell pour lancer les scripts, toujours en héritant sans le savoir d'un descripteur, et ces scripts finissent par lancer httpd, qui en hérite à son tour. Les shells lancés par system() finissent par mourir, et httpd par s'émanciper en se rattachant au processus init, mais ce serveur web reste bien, malgré lui, le dernier et le plus récent dépositaire de ton descripteur de socket, lequel reste ouvert tant qu'un processus a la main dessus.

    Si tu ouvres une fenêtre en parallèle et que tu fais :

    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ while true ; do clear ; netstat -ltnp | grep 9990 ; sleep 1 ; done
    

    … tu verras le port concerné changer de propriétaire dès que ton programme se terminera.

    Pour éviter ça, il faut passer l'attribut O_CLOEXEC lorsque l'on utilise open(), de façon à ce que les descripteurs concernés soient automatiquement fermés chez les fils. Comme tu ne peux pas passer l'option à socket(), il faut utiliser fcntl() comme expliqué derrière ce lien :

    http://pubs.opengroup.org/onlinepubs...g_03_141_06_02

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    244
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 244
    Points : 159
    Points
    159
    Par défaut
    Merci beaucoup pour vos réponses et vos recherches !!

    Je vais tenter comme tu me l'indiques et je reviendrai bien entendu donner le résultat de tout ça!

    Merci!
    L'informatique au service de l'écologie avec ecomail.fr - Mon hébergeur : Microheb

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    244
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 244
    Points : 159
    Points
    159
    Par défaut
    Bonsoir,

    Ta technique fonctionne. Merci encore!

    Si quelqu'un a besoin de détail sur le code, je peux répondre par PM
    L'informatique au service de l'écologie avec ecomail.fr - Mon hébergeur : Microheb

  12. #12
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Citation Envoyé par furtif1 Voir le message
    Ta technique fonctionne. Merci encore!
    De rien, mais n'oublie pas !

    Si quelqu'un a besoin de détail sur le code, je peux répondre par PM
    Pourquoi par message privé ? Si tu bénéficies de l'aide de la communauté, autant la faire profiter en retour du résultat. Dans ce cas, ce fil est l'endroit le plus indiqué pour cela.

  13. #13
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Je me permet de m'imiscer dans la conversation, mais quand on fait un fork, la table des fd est dupliquer si je me souviens bien donc le socket est ouvert, il suffit de closer le socket dans le processus fils pour le fermer correctement avant de faire un system non?

    et ptite question au passage, pourquoi utiliser system et non pas execve ou fonction semblable?
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  14. #14
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Citation Envoyé par skeud Voir le message
    Je me permet de m'imiscer dans la conversation, mais quand on fait un fork, la table des fd est dupliquer si je me souviens bien donc le socket est ouvert, il suffit de closer le socket dans le processus fils pour le fermer correctement avant de faire un system non?
    Oui… avant de faire le fork() ! Et ce n'est pas forcément ce qu'il veut. Le problème est de lancer une commande donnée sur action à distance de l'utilisateur. Ça veut dire que l'on souhaite conserver ouverte la connexion, mais pas la transmettre à ses fils.

    et ptite question au passage, pourquoi utiliser system et non pas execve ou fonction semblable?
    execve() t'oblige à forker toi-même au préalable, mais c'est une bonne chose si on doit garder la disponibilité pour dialoguer avec le client, effectivement…

  15. #15
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Et si il close la socket dans le fils et non pas avant, la connection reste ouverte dans le pere mais est fermee dans le fils
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  16. #16
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Citation Envoyé par skeud Voir le message
    Et si il close la socket dans le fils et non pas avant, la connection reste ouverte dans le pere mais est fermee dans le fils
    O_CLOEXEC sert justement à ne pas avoir à le faire explicitement, d'une part, et à informer le système de tes intentions réelles, d'autre part.

    Pour execve() vs system(), ça ne se justifiait que parce qu'on souhaite forker pour lancer la commande de manière asynchrone (sinon il faudrait attendre que le script ait fini pour répondre au client)… et encore ! Autrement, ça n'a aucun intérêt dans le cas présent. Ton précédent commentaire était donc censé mais là, ça ressemble plus à une tentative pour justifier un postulat posé arbitrairement au départ.

  17. #17
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Ah ok pardon, pour le execve j'avais compris, et je ne cherchais pas a justifier mon post, je me posais reellement la question, et je n'avais pas vu les macro, je pensais pas qu'il utilisait les socket de cette maniere.

    Desoler pour le derangement.
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  18. #18
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Citation Envoyé par skeud Voir le message
    Ah ok pardon, pour le execve j'avais compris, et je ne cherchais pas a justifier mon post, je me posais reellement la question, et je n'avais pas vu les macro, je pensais pas qu'il utilisait les socket de cette maniere.

    Desoler pour le derangement.
    Tu ne déranges pas. Et la discussion est constructive.

    Pour la « justification », ce n'était pas une attaque personnelle mais un cas de figure malheureusement récurrent chez les chefs de projets, développeurs et architectes système, qui est d'autant plus sournois qu'il est généralement inconscient.

    Il arrive souvent que les critères ayant conduits à faire un choix au départ changent au cours de la phase d'analyse au point de le rendre caduque. Et il faut absolument être capable de le reconnaître, surtout si nos choix vont être imposés à une équipe par la suite.

  19. #19
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Il arrive souvent que les critères ayant conduits à faire un choix au départ changent au cours de la phase d'analyse au point de le rendre caduque. Et il faut absolument être capable de le reconnaître, surtout si nos choix vont être imposés à une équipe par la suite.
    Je suis bien d'accord, mes projets n'ont jamais la meme tete a la conception et apres le developpement, toujours une idee qui vient a un moment ou un autre qui change radicalement la vision du projet
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  20. #20
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    244
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 244
    Points : 159
    Points
    159
    Par défaut
    Salut tous le monde,

    Tu as raison Obsidian, je peux mettre le code ici :

    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
    //On cre le socket
    logger("cluster: Creation du socket port 9993");
    if((socket_server = socket(AF_INET, SOCK_STREAM, 0))<0)
    {
    	logger("cluster: Creation de la socket impossible. Arret du service.");
    	exit(0);
    }
     
    int flags;
     
    flags = fcntl(socket_server, F_GETFD);
    if (flags == -1)
    	logger("Erreur fcntl socket_server");
     
    flags |= FD_CLOEXEC;
     
    if (fcntl(socket_server, F_SETFD, flags) == -1)
    	logger("Erreur fcntl socket_server");
    L'informatique au service de l'écologie avec ecomail.fr - Mon hébergeur : Microheb

Discussions similaires

  1. Réponses: 5
    Dernier message: 16/11/2006, 10h50
  2. Lancer un process avec les droits d'un autre utilisateur
    Par devl83 dans le forum Administration système
    Réponses: 2
    Dernier message: 26/06/2006, 11h03
  3. lancer un process en background
    Par yoda1410 dans le forum C++Builder
    Réponses: 1
    Dernier message: 28/04/2006, 20h32
  4. [C#] Comment lancer un process dans cmd.exe ?
    Par freddyboy dans le forum C#
    Réponses: 2
    Dernier message: 23/01/2006, 12h45
  5. Lancer un process dès qu'il tombe
    Par devdev2003 dans le forum Administration système
    Réponses: 4
    Dernier message: 13/06/2005, 22h44

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