Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
727 connectés 

  FORUM HardWare.fr
  Programmation
  C

  programme c

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

programme c

n°1575945
chris1720
Posté le 17-06-2007 à 10:27:40  profilanswer
 

Bonjour tout le monde,  
 
J'ai vu qu'on pouvait laisser un message pour une aide en programmation. Je suis débutante dans ce langage et les cours que je suis sont malheureusement pas top donc j'essaie de trouver de l'aide ailleurs :  
 
En gros je ne sais pas exactement ce que fait ce programme ? à part qu'il y création d'un processus pere et fils et echange de données. Par contre je ne comprends pas la fonction de execlp.  
 
 
int main()  
{  
int pfds[2];  
int pfds_bis[2];  
pipe(pfds);  
 
if(0==fork()){  
dup2(pfds[0],0);close(pfds_bis[1]);  
pipe(pfds_bis);  
if(0==fork()){  
dup2(pfds_bis[0],0);close(pfds_bis[1]);  
execlp("grep","grep","cnam",NULL);  
}else{  
dup2(pfds_bis[1],1);close(pfd_bis[0]);  
execlp("grep","grep","2006",NULL" );  
}  
}else}  
dup2(pfds[1],1);close(pfds[0]);  
execlp("ls","ls",NULL);  
}  
}
 

mood
Publicité
Posté le 17-06-2007 à 10:27:40  profilanswer
 

n°1575953
Sve@r
Posté le 17-06-2007 à 12:21:05  profilanswer
 

chris1720 a écrit :

Bonjour tout le monde,  
 
J'ai vu qu'on pouvait laisser un message pour une aide en programmation. Je suis débutante dans ce langage et les cours que je suis sont malheureusement pas top donc j'essaie de trouver de l'aide ailleurs :  
 
En gros je ne sais pas exactement ce que fait ce programme ? à part qu'il y création d'un processus pere et fils et echange de données. Par contre je ne comprends pas la fonction de execlp.


 
ok. Beaucoup de choses à dire
Tout d'abord, pour bien illustrer ton code, il est nécessaire que tu l'encadres entre des balises [ FIXED ]  [ /FIXED ]  ou [ CPP ] [ /CPP ] (moi j'ai mis des espaces après les crochets car je veux les montrer mais pour que le forum les interprètes, faut pas que tu mettes d'espace).
Ton code ressortira et sera formaté comme il faut.
 
Ensuite, je trouve assez étonnant qu'on enseigne aux débutant(e)s des notions comme le pipe et le fork. Ce sont plutôt des notions approfondies de travail sur Unix/Linux. Je vais pas les redévelopper ici étant donné que j'ai écrit un cours complet sur ces outils quand j'enseignais Unix. Tu trouveras ce cours en téléchargement ici http://fr.lang.free.fr/cours/Processus_Csyst_v1.0.pdf
 
Sinon tu as fait une petite erreur. Il n'y a pas création d'un processus père et fils, il y a un processus (le père) qui crée un second processus (le fils) qui lui-même crée un 3° processus. Donc si on résume le truc, le p1 est le père de p2 qui est lui-même le père du p3. Et p3 est fils de p2 qui est lui-même fils de p1. Sous Unix, les parentés ne vont que 2 par 2 (un père connait son fils et un fils connait son père mais un père ne connaît pas le fils de son fils et donc p1 n'a aucune connaissance de p3)
 
Voici ton code réécrit avec les commentaires qui vont bien
 

int main()  
{  
    int pfds[2];  
    int pfds_bis[2];  
 
    // Création d'un canal de communication destiné à faire communiquer 2 processus (celui-ci P1 et son fils P2)
    pipe(pfds);  
 
    // Création d'un processus fils
    if(0==fork()){
        // On est dans le fils P2
 
        // On associe l'entrée standard (clavier) à l'entrée du canal pfds => toute info dans le clavier sera lisible dans le canal
        dup2(pfds[0],0);
 
        // On ferme le coté du canal associé à l'écriture => ce processus ne fera que lire le canal mais n'y écrira pas dedans
        close(pfds_bis[1]);  
 
        // On crée un nouveu canal de communication pour deux processus (celui-ci et son fils)
        pipe(pfds_bis);  
 
        // Création d'un fils (dans le fils)        
        if(0==fork()){
             // On est dans le fils P3 (du fils)  
 
             // On associe ici aussi l'entrée standard (clavier) sur l'entrée du canal pfds_bis
             dup2(pfds_bis[0],0);
 
             // Ici aussi, ce processus n'a pas besoin d'écrire dans pfds_bis (il ne fait que lire)
             close(pfds_bis[1]);  
 
             // Le processus P3 disparaît et il est remplacé par celui du programme "grep"
             // Petit détail: le grep prend ses infos dans l'entrée standard qui a été associée au canal de lecture de pfds_bis
             // Donc tout ce qui arrive dans pfds_bis ira dans le grep
             execlp("grep","grep","cnam",NULL);  
        }
        else{  
             // On est dans le fils P2
 
             // On associe la sortie standard (écran) sur le canal d'écriture de pfds_bis
             dup2(pfds_bis[1],1);
 
             // Ce processus P2 n'ayant pas besoin de lire le canal pfds_bis, on ferme la partie destinée à la lecture              
             close(pfd_bis[0]);
 
             // Ce processus P2 disparait et il est remplacé par "grep"
             // Toute info affichée par grep sera écrite dans le canal
             execlp("grep","grep","2006",NULL" );  
 
             // Et comme ce processus a associé son entrée standard à pfds, toute info dont le grep a besoin sera prise dans pfds
        }  
     }
     else{  
         // Ici on est dans le père P1
 
         // On associe la sortie standard (écran) sur le canal d'écriture de pfds => toute info écrite à l'écran sera écrite dans pfds
         dup2(pfds[1],1);
 
         // Ce processus P1 n'ayant pas besoin de lire le canal pfds, on ferme la partie destinée à la lecture
         close(pfds[0]);  
 
         // Ce processus P2 disparait et il est remplacé par "ls"
         // Toute info affichée par ls sera écrite dans le canal pfds
         execlp("ls","ls",NULL);  
     }  
}


 
Donc si je comprends bien, ce programme fait un "ls |grep 2006 |grep cnam"


Message édité par Sve@r le 17-06-2007 à 12:44:00

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1575988
chris1720
Posté le 17-06-2007 à 16:33:51  profilanswer
 

Merci enormement pour votre réponse, votre niveau d'enseignement est trés bon (car j'ai tout compris :) et niquel votre cours
 
Dans la lancée pouvez vous egalement m'eclairer sur ce programme :  
 

Code :
  1. int Continuer=1;
  2. void action (int SIG)
  3. { //SIG vaut la valeur du signal qui l'a déclenché  
  4. switch(SIG)
  5. {
  6. case SIGSTOP:
  7. printf("SIGNAL:SIGSTOP attrape\n" );
  8. Continuer=0;
  9. break;
  10. case SIGINT:
  11. printf("SIGNAL : SIGINT attrape\n" );
  12. break;
  13. case SIGUSR1:
  14. printf("SIGNAL : SIGUSR1 attrape\n" );
  15. break;
  16. default;
  17. printf("SIGNAL:Signal Inconnu\n" );
  18. }
  19. }
  20. int main (int argc,char*argv[]){
  21. signal(SIGSTOP,action);
  22. signal (SIGINT,action);
  23. while (Continuer)
  24. {
  25. kill(getpid(),SIGINT);
  26. sleep(1)
  27. kill(getpid(),SIGUSR1);
  28. sleep(1);
  29. kill(getpid(),SIGSTOP);
  30. }
  31. exit(0);
  32. }


 
si j ai bien compris le signal(SIGSTOP, action) va afficher "SIGSTOP attrappe" et passer Continuer à 0 et on sort de la fonction action.
 
ensuite signal(SIGINT) va afficher "SIGINT attrappe" et on sort de la fonction action.
 
Et on ne rentre pas dans la boucle while parce que la condition est fausse car Continuer est à 0.
 
Au final à l'écran on aura : SIGTOP attrappe
                                    SISGINT attrappe
 
Est-ce bien cela?

n°1576051
Sve@r
Posté le 17-06-2007 à 23:25:02  profilanswer
 

chris1720 a écrit :


si j ai bien compris le signal(SIGSTOP, action) va afficher "SIGSTOP attrappe" et passer Continuer à 0 et on sort de la fonction action.
 
ensuite signal(SIGINT) va afficher "SIGINT attrappe" et on sort de la fonction action.
 
Et on ne rentre pas dans la boucle while parce que la condition est fausse car Continuer est à 0.
 
Au final à l'écran on aura : SIGTOP attrappe
                                    SISGINT attrappe
 
Est-ce bien cela?


Pas tout à fait.
 
La fonction "signal()" a pour but d'armer (préparer) une action. Mais cette action ne se fera QUE si le processus reçoit un signal (ne pas confondre "recevoir un signal" et "fonction signal()" ).
 
Par défaut, quand un processus reçoit un signal (envoyé généralement par le biais du kill), il s'arrête. Les noob concluent que "kill" signifie "tuer un processus" mais en fait, cela signifie juste "envoyer un signal à un processus".
Donc quand un processus reçoit un signal, il s'arrête. C'est le comportement par défaut. Mais ce comportement peut être changé.
Il suffit, dans le programme, de  
1) écrire une fonction de type "void" et recevant un paramètre "int". Ces éléments sont obligatoires.
Ex:

void toto(int x)
{
....
}


 
2) préparer le processus à recevoir un signal x en lui disant "si tu reçois le signal x, faudra que tu lances toto => ex: signal(x, toto)
 
A partir de là, c'est fini. Le programme se déroule normallement. MAIS s'il reçoit le signal "x", alors toto sera automatiquement appelé. Mais s'il ne reçoit pas le signal "x", alors toto ne sera jamais exécuté. Voir p. 11 et suivantes du même cours que ce matin...
 
Donc ici, action() ne sera appelée que si le processus reçoit un signal SIGINT ou SIGSTOP. La variable globale "continuer" servant à la gestion interne de "action()" car cette fonction ne peut pas recevoir d'autres paramètres.
 
 


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1576253
matafan
Posté le 18-06-2007 à 13:56:13  profilanswer
 

Juste pour dire que la réponse par défaut d'un programme à un signal dépend du signal. Pour un bon paquet de signaux (SIGTERM, SIGKILL, SIGINT, SIGSEGV, SIGTRAP...) c'est effectivement de terminer le programme, mais pour d'autre l'action est différente. SIGSTOP par exemple va suspendre l'éxécution du programme, et SIGCONT va reprend l'exécution d'un programme stoppé.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  programme c

 

Sujets relatifs
[Résolu]Programme supprimant les commentaires d'un fichier CRésolu - Problème d'éxécution programme VB Express
Autoexecution d'un programmeParamètre du programme
programme pour recupérer des mailséxécution anormale de programme compile VC6
[C][Windows] Récupérer le PID d'un programme[VBA-E]souci avec un programme
Appeller un programme en html/javascriptprogramme utilisant API Windows et GNU Scientific Librairy
Plus de sujets relatifs à : programme c


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR