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 :

Controle de processus [Débutant]


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Par défaut Controle de processus [Débutant]
    Salut les C,
    je n'arrive pas a contrôler les processus créer avec un|des appels a fork(),
    Le problème réside dans l'arrêt des processus et de reprise de contrôle par le processus parent.
    Je suppose, a tord, que si je lance un nouveau processus (dans un bloque conditionnel):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if ((child_pid=fork()) != -1) { 
      //le processus fils exécute son code puis retourne
      return 0 ;
    }
    et que celui ci exécute son code puis retourne, le processus parent reprend le contrôle et le processus fils est arrêter, seulement d'après mes expérience ce n'est pas le cas:
    le processus parent ne reprend pas le contrôle et si je termine pas le processus fils le code est exécuter doublement (vérifiable par un appel a printf() exécuter plusieurs fois).
    Prenons l'exemple suivant (que j'espère que vous ne jugerai pas immoral et que vous prendrez avec humours) afin que vous puissiez me guider:
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <time.h>
    #include <signal.h>
     
    int main() {
      pid_t child_1,child_2 ;
      pid_t master ;
      int waiting ;
      time_t randseed ;
      time(&randseed) ;
      srand(randseed/8) ;
      waiting=rand() % 15 ;
      time_t wait_time_start ;
      time_t wait_time_end ;
      int waiting_time ;
      char *child_2_say="child_2 say: ";
      char *child_1_say="child_1 say: ";
      int c ;
     
      master=getpid() ;
     
     
      c=0 ;
      printf("master pid: %i\n",master) ;
      fork() ;
      child_1=getpid() ;
      fork() ;
      child_2=getpid() ;
      time(&wait_time_start) ;
      while ( c < waiting) {
        if ( getpid() == child_1 && (c == waiting-2 || c == waiting-1) ) {
          /* kill() ou return au choix pour finir le processuss */
          printf("child_1 killed\n") ;
          kill(child_1,SIGTERM) ;
          //return 0 ;          
        }
        else if ( getpid() == child_2 && (c == waiting-2 || c == waiting-1) ) {
          /* kill() ou return au choix pour finir le processuss */
          printf("child_2 killed\n") ;
          kill(child_2,SIGTERM) ;
          //return 0 ;
        }
        else if (getpid() == child_1) {
     
    	time(&randseed) ;
            srand(randseed/8) ;
            sleep(rand() % waiting) ;
    	printf("%s i wait %i seconds\n",child_1_say,rand() % waiting) ;
        }
     
        else if (getpid() == child_2) {
     
    	time(&randseed) ;
            srand(randseed/8) ;
    	sleep(rand() % waiting) ;
    	printf("%s i wait %i seconds\n",child_2_say,rand() % waiting) ;
        }
     
        sleep(1) ;
        c++ ;
     
      }
     
      /* cette partie n'est jamais exécuter
       * a moins d'enlever les appels a kill() et|ou return:
       * dans ce cas elle est exécuter 4 fois (voir appel a printf()) */ 
     
     
      time(&wait_time_end) ;
      waiting_time=difftime(wait_time_end,wait_time_start) ;
     
      printf("We have wait %i seconds\n",waiting_time) ;
      return 0 ;
     
    }
    Je comprend parfaitement que le code est exécuter plusieurs fois si il y a plusieurs processus mais pas pourquoi le processus père ne reprends pas le contrôle.
    J'ai essayer avec la fonction waitpid() sans succès.

    Je sais que le sujet n'est pas facile et je vous serai grandement reconnaissant de bien vouloir me donner des conseils afin d'éclairer mon ignorance sur le sujet.

    J'attends vos réponses éclairées avec impatience.

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Bonjour,

    Qu'entends-tu par "reprendre le contrôle" ?

    Quand tu fais un fork, le code qui suit est exécuté simultanément par deux processus : le père et le fils.

    Ensuite, il est possible pour le père d'attendre la fin d'un processus fils avec wait().

    Sinon, "l'humour" contenu dans ton code n'est pas utile à la compréhension de ce dernier et vu qu'il est (un peu) "douteux", je te conseillerais d'éditer pour l'enlever

  3. #3
    Membre éprouvé
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Par défaut
    J'ai laisser mon humours au vestiaires.
    Je voulais dire par reprendre le contrôle de pouvoir exécuter du code par un processus et d'avoir le contrôle sur qui fait quoi:
    -Pouvoir faire exécuter du code uniquement par le processus voulus.
    -Pouvoir stopper le processus voulus.
    -> Suite a quoi le processus parent continue: le problème dans le code exemple.
    Mais avec des appels a fork() je n'arrive pas a faire ce que je veut proprement et ca se mélange.

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 398
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 398
    Par défaut
    Les deux processus tournent en parallèle après le fork(); si tu veux en bloquer l'un ou l'autre, tu utilises des objets de synchronisation (sémaphores, etc.)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Bonjour,

    à la lecture de ton code je m'aperçois que tu ne comprends pas comment fonctionne fork. Je ne vais pas débuguer ton programme car de toute façon il va falloir que tu le réécrives. Je vais néanmoins t'orienter vers des références qui vont te permettre de comprendre le fonctionnement de fork.

    Tout d'abord la man page de fork. La partie exemple te donne le squelette classique d'un appel à fork :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    pid_t   pid;
     
        pid = fork ();
     
        if (pid > 0) {
             /* Processus père      */
        } else if (pid == 0) {
             /* Processus fils      */
        } else {
             /* Traitement d'erreur */
        }
    Dans cet exemple qui est très succinct, tu vois que par rapport à ton essai infructueux :
    • le retour de l'appel à fork est mémorisé
    • il y a une gestion des erreurs
    • il y a une partie qui sera exécutée par le père et une par le fils


    Pour te donner un aperçu de «comment ça fonctionne» :
    1. tu lances ton programme = il existe en mémoire et est exécuté (c'est un processus)
    2. l'exécution arrive sur un appel à fork
      • l'OS duplique ton programme : il existe maintenant en deux exemplaire en mémoire (il y a deux processus)
      • les deux copies sont identiques et indépendantes (on simplifie dans un premier temps, car cette affirmation est fausse mais suffisamment correcte pour comprendre) à un détail près : la valeur de retour de fork. Dans une des copies elle vaut 0, cette copie est appelée Fils, dans l'autre est ne vaut pas 0, cette copie est appelée Père.
      • que ce soit dans le père ou dans le fils, la ligne qui suit l'appel à fork sera exécutée. C'est pourquoi il y a le test sur la valeur de retour de fork : c'est le seul moyen de savoir dans quelle copie on se trouve (0 -> on est dans le Fils, différent de 0 -> on est dans Père).


    Je pense que cette explication devrait répondre à la partie

    Je voulais dire par reprendre le contrôle de pouvoir exécuter du code par un processus et d'avoir le contrôle sur qui fait quoi:
    -Pouvoir faire exécuter du code uniquement par le processus voulus.
    Quant à la partie
    -Pouvoir stopper le processus voulus.
    Tu peux utiliser wait ou waitpid (il y a un lien vers leur man page dans le lien sur la man page de fork donné un peu plus haut).
    Tu peux aussi utiliser kill pour tuer le Fils (ou plus généralement lui envoyer un signal), ou tu peux communiquer avec lui en utilisant les IPC (inter process communication). Je t'encourage à chercher la man page de kill, et googler IPC pour avoir des exemples. Il y a plusieurs moyen de faire (plusieurs API, des approches différentes) mais je ne m'étendrai pas là-dessus car je me pose une question :

    tu utilises (un peu ... du moins dans l'intention affichée) les forks comme si tu utilisais des threads ... es-tu certain de ne pas confondre les deux ? Jette un coup d'oeil sur : Thread et fork.

  6. #6
    Membre éprouvé
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Par défaut
    Merci pour ces éclaircissements kwariz
    Je confond effectivement les fork() avec les thread (j'ai même essayer de faire communiquer 2 processus comme on fait communiquer des sockets) et je comprend pas encore l'utilité de fork() si celui crée une copie du processus comme tu l'a expliquer:
    -> Pour faire faire une tache au programme de manière synchrone il y a les threads.
    -> pour lancer une commande il y a les exec() ou system() qui correspondent a un appel a fork() puis un exec() a l'intérieur de celui-ci (corriger moi si je me trompe)

    Je crois qu'un thread a les même variables globale que le processus qui le lance alors qu'un fork() créer une nouvelle instance du processus qui le lance (Je sort ça des modes de fonctionnement d'apache qui peut fonctionner en mode thread, en mode fork ou les deux).

    Je pense que me donner un exemple d'utilité d'un fork() m'éclairerai.
    (Apache fait un fork() pour chaque client qui se connecte en même temps...)

    Concernant wait() et waitpid() j'ai essayer sans succès.
    J'ai toujours l'impression que je n'ai pas le contrôle de qui fait quoi avec les fork().

    Je vais me renseigner sur les IPC j'ai dans ma bibliothèque le livre de Blaess que je n'ai pas encore commencer car je suis encore débutant intermédiaire en C et que c'est peut-être pas encore le moment (ca fait que 5 mois et demi que je fait du C) et ce livre ne s'adresse pas aux débutants.

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

Discussions similaires

  1. [DB400][Débutant]comprendre la gestion des processus actif
    Par horalass dans le forum Autres SGBD
    Réponses: 8
    Dernier message: 12/12/2006, 09h26
  2. [Débutant] Recherche controle ActiveX
    Par Invité dans le forum MFC
    Réponses: 2
    Dernier message: 19/10/2005, 17h01
  3. Contrôle d'exécution de processus
    Par TB38570 dans le forum Linux
    Réponses: 3
    Dernier message: 07/12/2004, 09h39
  4. Controler un nombre de processus identiques.
    Par ditfau6 dans le forum Shell et commandes GNU
    Réponses: 2
    Dernier message: 24/05/2004, 16h21
  5. [débutant][control]SS_BITMAP
    Par vvidal80 dans le forum MFC
    Réponses: 6
    Dernier message: 13/01/2004, 15h00

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