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 :

comment implémenter avec fork un appel de fonction engendrant un processus?


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 371
    Par défaut comment implémenter avec fork un appel de fonction engendrant un processus?
    bonjour,

    J'ai lu un peu la doc de fork.
    Je n'arrive pas à implémenter un programme program.c faisant ceci en pseudo-code:
    creation d'une fonction simple f1
    création d'ue fonction simple f2
    si f1 est appelée,ça engendre un processus p1
    si f2 est appelée,ça engendre un processus p2



    merci de votre aide

  2. #2
    Membre expérimenté

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    329
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 329
    Par défaut
    Oui...

    fork() est un mécanisme particulier...

    J'ai pour habitude lorsque j'utilise fork() de récupérer sa valeur de retour.

    [EDIT après avoir relu le man :} ]

    Grâce à celle-ci je peux déterminer
    + le processus père
    + le processus fils (child) enfant


    Le processus père enfant sera le bloc d'instructions exécuté si la valeur de retour du fork() est égale à 0.
    Le processus enfant père sera le bloc d'instructions exécuté si la valeur de retour du fork() est différente de 0 (correspondant à l'identifiant de processus enfant).

    Dans ton cas, il faudrait appeler la fonction f1 dans le bloc correspondant au "père", et du coup la fonction f2 sera appelée dans le bloc correspondant au "fils" à l'enfant.

    Exemple:
    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
     
    #include  <stdio.h>
    #include  <sys/types.h>
     
    #define   MAX_COUNT  200
     
    void  ChildProcess(void);                /* child process prototype  */
    void  ParentProcess(void);               /* parent process prototype */
     
    void  main(void)
    {
         pid_t  pid;
     
         pid = fork();
         if (pid == 0) 
              ChildProcess();
         else 
              ParentProcess();
    }
     
    void  ChildProcess(void)
    {
         int   i;
     
         for (i = 1; i <= MAX_COUNT; i++)
              printf("   This line is from child, value = %d\n", i);
         printf("   *** Child process is done ***\n");
    }
     
    void  ParentProcess(void)
    {
         int   i;
     
         for (i = 1; i <= MAX_COUNT; i++)
              printf("This line is from parent, value = %d\n", i);
         printf("*** Parent is done ***\n");
    }
    -- from https://www.csl.mtu.edu/cs4411.ck/ww...rk/create.html --

  3. #3
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 548
    Par défaut
    Bonjour,
    Citation Envoyé par hurukan Voir le message
    Oui...

    fork() est un mécanisme particulier...

    J'ai pour habitude lorsque j'utilise fork() de récupérer sa valeur de retour.

    Grâce à celle-ci je peux déterminer
    + le processus père
    + le processus fils

    Le processus père sera le bloc d'instructions exécuté si la valeur de retour du fork() est égale à 0.
    Le processus fils sera le bloc d'instructions exécuté si la valeur de retour du fork() est différente de 0.

    .......
    Attention, après le retour d'un fork les deux contextes d'exécution (processus père et fils) reçoivent tous les deux une valeur de retour qui sont différentes. L'enfant reçoit du fork la valeur de retour zéro (0) tandis que le père reçoit comme valeur de retour l'identifiant du processus enfant et donc différent de zéro. En termes plus clairs, le père reçoit le PID du nouveau processus fils, ce qui permettra à la fois au père et au fils de savoir qui est qui. Le cas contraire où la primitive fork renvoie la valeur -1 en cas d'échec cela peut être dû (très souvent) au fait que nous avons atteint la limite des processus fils auxquels un père peut posséder ou à un manque d'espace qui empêche la création d'une entrée dans la table des processus ou à une mémoire virtuelle insuffisante.

    Aussi la création de processus est très utile mais il faut faire attention car si l'entrée d'un enfant dans la table des processus se fait facilement, ce n'est pas le cas des suppressions immédiates de celle-ci. En effet bien que l'enfant ne soit pas/plus actif, son contexte d'exécution aux yeux du système reste dans la mesure où son code de retour doit être stocké en cas d'appel à wait et donc on parle de processus zombie, surtout si l'enfant se termine avant le père.


    Pour le débutant je dirais juste que lors de la création d'un processus avec la primitive fork vous obtiendrez pour le père une valeur de retour qui est égale au processus Identifer qui est surnommé PID du fils et pour le fils le PID = zéro. En cas d'erreur vous obtenez une valeur négative. Aussi, Il faut toujours éviter qu'un processus soit dans un état zombie en utilisant des primitives comme Wait mais je vous laisse le soin de vous documenter après avoir compris comment fonctionne fork et comment les utiliser.

    à bientôt.

  4. #4
    Membre très actif
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 371
    Par défaut
    quel est le rapport avec la fonction appelée qui déclenche un processus?

    Ma fonction f1 appelée serait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int somme (int a,int b)
    { int c;
       c=a+b;
      return c;
    }
    Ma fonction f2 appelée serait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int difference (int a,int b)
    { int c;
       c=a-b;
      return c;
    }
    Ce code là serait-il alors correct?
    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
     
     
    #include  <stdio.h>
    #include  <sys/types.h>
     
    #define   MAX_COUNT  200
     
    void  ChildProcess(void);                /* child process prototype  */
    void  ParentProcess(void);               /* parent process prototype */
     
    void  main(void)
    {
         pid_t  pid;
     
         pid = fork();
         if (pid == 0) 
              ChildProcess();
         else 
              ParentProcess();
     
      if(somme(0,1)==1)
    {
    ParentProcess();   
    }
     
    if(difference(1,0)==1)
    {
    ChildProcess();  
    }
     
    }
     
    void  ChildProcess(void)
    {
         int   i;
     
         for (i = 1; i <= MAX_COUNT; i++)
              printf("   This line is from child, value = %d\n", i);
         printf("   *** Child process is done ***\n");
    }
     
    void  ParentProcess(void)
    {
         int   i;
     
         for (i = 1; i <= MAX_COUNT; i++)
              printf("This line is from parent, value = %d\n", i);
         printf("*** Parent is done ***\n");
    }
     
    int somme (int a,int b)
    { int c;
       c=a+b;
      return c;
    }
     
    int difference (int a,int b)
    { int c;
       c=a-b;
      return c;
    }

  5. #5
    Membre expérimenté

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    329
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 329
    Par défaut
    Je dirais: si tu veux tenter d'appréhender les mécanismes liés au fork() -- je m'étais planté avec les notions de parent/enfant père/enfant, j'utilise principalement les threads (corrigé suite aux précisions de sambia) --
    tu pourrais, par exemple, tester les instructions de la fonction somme() dans le processus enfant d'un fork()... de même pour soustraction().

    Maintenant la nature de ces fonctions ne te permettra pas d'appréhender réellement les mécanismes liés à l'appel système fork()...
    Moi j'ai utilisé fork() pour créer des drivers, des "daemons" (serveurs dans le monde Unix)... ils sont censés être en attente que "quelque chose se passe" et réagissent
    quand les conditions sont remplies (un périphérique USB se connecte par exemple, une demande de connexion TCP est reçue, ...).

    En général ces "serveurs" tournent en arrière plan dans une "boucle infinie" (pour ne pas monopoliser toutes les ressources du système) qui ne s'arrête que lorsque un message (signal) précis est envoyé au processus (SIGHUP, ...).

    [EDIT]
    Je ne suis pas certain que le compilateur va aimer ces instructions
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    if(somme(0,1)==1)
    {
    ParentProcess();   
    }
     
    if(diiference(1,0)==1)
    {
    ChildProcess();  
    }
    ...en fin de listing.

  6. #6
    Membre expérimenté

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    329
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 329
    Par défaut
    Il vaut mieux afficher quelque chose...

    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
    #include  <stdio.h>
    #include  <sys/types.h>
     
    void  ChildProcess(void);                /* child process prototype  */
    void  ParentProcess(void);               /* parent process prototype */
     
    void  main(void)
    {
         pid_t  pid;
     
         pid = fork();
         if (pid == 0) 
              ChildProcess();
         else 
              ParentProcess();
    }
     
    void  ChildProcess(void)
    {
      int c;
      c=a+b;
      //return c;
      printf("Somme de %d et %d = %d\n",a,b,c);
    }
     
    void  ParentProcess(void)
    {
      int c;
      c=a-b;
      //return c;
      printf("Différence de %d par %d = %d\n",a,b,c);
    }
    Tu pourrais "voir" le côté "exécution en parallèle" si tu faisais une boucle infinie autour des deux opérations...
    Comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    while(1)
    {
      c=a+b;
      printf("Somme de %d et %d = %d\n",a,b,c);
      a++;
      b++;
    }
    ...tu devras probablement effectuer un CTRL-C pour arrêter le programme ^^

  7. #7
    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
    Bonjour
    Citation Envoyé par tabkelm Voir le message
    Je n'arrive pas à implémenter un programme program.c faisant ceci en pseudo-code:
    creation d'une fonction simple f1
    création d'ue fonction simple f2
    si f1 est appelée,ça engendre un processus p1
    si f2 est appelée,ça engendre un processus p2
    Déjà ce serait bien que tu réalises que f1 et f2 c'est la même chose.

    Citation Envoyé par tabkelm Voir le message
    Mais je souhaite que se crée en fait un autre processus:comment implémenter ceci?)
    Code c : 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
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <sys/wait.h>
     
    void f() {
    	int pid;
    	int status;
    	switch(pid=fork()) {
    		case -1: // Erreur
    			fprintf(stderr, "Erreur fork() - %s\n", strerror(errno));
    			break;
    		case 0: // Fils
    			printf("\tJe suis le fils %d de %d\n", getpid(), getppid());
    			sleep(10);
    			exit(123);
    			break;
    		default: // Pere
    			sleep(1);		// Pour être sûr que le fils sera lancé avant le père
    			printf("Je suis le pere %d de %d\n", getpid(), pid);
     
    			// Attente fin fils
    			int p=wait(&status);
    			printf("Fils %d(=%d) terminé (%d)\n", p, pid, WEXITSTATUS(status));
    	}
    }
     
    int main() {
    	f();
    }

    Citation Envoyé par hurukan Voir le message
    La fonction main() cache un fork()... si mes souvenirs sont bons.
    Absolument pas. C'est le shell qui cache un fork. Quand tu lances une commande shell (ou un programme) le shell lance un fork et c'est le shell fils qui se charge d'exécuter le programme pendant que le père attend la fin (un peu comme mon code où le père attend la fin du fils).
    Et c'est grâce à ce système que tu peux lancer un programme en arrière plan via le "&". Dans ce cas rien ne change sauf que le père n'attend pas la fin du shell fils.
    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]

Discussions similaires

  1. [AC-2003] Comment appeler une fonction avec deux paramètres. Erreur '=' attendu
    Par nirG95 dans le forum VBA Access
    Réponses: 1
    Dernier message: 02/09/2009, 10h53
  2. Comment appeler une fonction externe avec XPath
    Par ttttnht dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 19/06/2009, 13h54
  3. Réponses: 2
    Dernier message: 30/10/2008, 18h30
  4. Réponses: 3
    Dernier message: 19/03/2008, 22h11
  5. [JQUERY] Comment appeler une fonction php avec jquery
    Par popogendarme dans le forum jQuery
    Réponses: 1
    Dernier message: 20/03/2007, 16h07

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