TP de C et IPC

TP de C et IPC - C - Programmation

Marsh Posté le 09-01-2010 à 16:16:10    

Bonjour,
 
Je poste ce message car j'ai un TP de C à faire manipulant les IPCs (sémaphores, files de messages, etc...)
Avant de poster ici j'ai longtemps chercher mais là, je sèche lamentablement  :sweat:  
 
Une chose avant de vous lancer la dedans, sachez que tous mes processus se compilent.
Je vous passe les détails inutiles de mon TP, le problème est simple :
J'utilise pour lier 2 processus une file de message (=boite aux lettres) afin que ces 2 derniers puissent par exemple dans un premier temps s'échanger leur PID respectifs.
Le 1er processus envoi bien son message (message de type 1), et le destinataire le reçoit bien. Le destinataire répond donc en envoyant a la file de message son PID (message de type 2). Mais j'ai essayé de lire ce dernier message avec plusieurs processus, et tous bloquent (ils se mettent en attente d'un message de type 2) à la commande : msgrcv(id_BAL,&message,100,2,0);
Chaque processus possède les même droit quant a cette file de messages : 0666 (lecture/écriture);
 
Je ne comprend pas pourquoi ils bloquent comme si aucun message de type 2 n'existait dans la file. Surtout que lorsque je tape la cmd shell ipcs, j'observe bien que ma file de messages contient plusieurs messages (en l'occurence ici, 2).
 
Si qqun a une petite idée d'où pourrait provenir le soucis merci de me le dire, parce que c'est assez chiant :D
 
Merci encore :)
 
PS : je tourne sous ubuntu 9.10, compile avec gcc et code sous VIM.

Reply

Marsh Posté le 09-01-2010 à 16:16:10   

Reply

Marsh Posté le 10-01-2010 à 13:06:04    

personne ne peut m'aider :( ???

Reply

Marsh Posté le 10-01-2010 à 19:25:34    

IPC System V, ça fait belle lurette que plus personne n'utilise cette API archaïque, remplacée par l'API Posix depuis un bout de temps. J'ai du mal à croire qu'on peut encore enseigner ce truc en 2010. Va engueuler ton prof et dis lui de se mettre à jour.
 
T'es vraiment obligé d'utiliser cette API de merde ??

Reply

Marsh Posté le 11-01-2010 à 19:32:51    

heu oui. Ne me demande pas pourquoi je n'en sais rien du tout :D
Je pensais pas que c'était si dépassé que ça !!
Je viens de regarder, bcp d'école d'ingé filière telecommunications (comme la mienne) enseigne ça. Il y a surement une bonne raison !
 
Enfin en tt cas merci d'avoir répondu :)
Si par chance qqun a étudié tout ça et qu'il sait me répondre ca serait qd même vachement aidant :D

Reply

Marsh Posté le 12-01-2010 à 17:02:37    

Plop,
* Si un seul processus produit le message et plusieurs le consomment, quand le retires tu de la file de message?
* Mets un IPC_NOWAIT et controle la valeur de retour du msgrcv pour avoir les details de l'erreur
 
* Fais péter le code pour plus d'aide... (bien que je ne sois pas un spécialiste ipc)

Message cité 1 fois
Message édité par breizhbugs le 12-01-2010 à 17:03:15
Reply

Marsh Posté le 12-01-2010 à 23:30:25    

breizhbugs a écrit :

Plop,
* Si un seul processus produit le message et plusieurs le consomment, quand le retires tu de la file de message?
* Mets un IPC_NOWAIT et controle la valeur de retour du msgrcv pour avoir les details de l'erreur
 
* Fais péter le code pour plus d'aide... (bien que je ne sois pas un spécialiste ipc)


 
* L'échange de PID par la file de messages ne se fait qu'entre 2 processus seulement, donc personne d'autre ne lis ces messages. Qu'est ce que tu entends par retirer de la file de message ?? Je n'ai jamais réellement eu en tête le fait de supprimer un message de la file après qu'il ai été lu, je pensais qu'après avoir été lu, il se supprimait de lui même
 
* avec le IPC_NOWAIT, il m'affiche mon printf d'erreur et passe à la suite, par contre, lui, réussi bien a envoyer son PID a l'autre !
 
* voilà le code du processus "code" et celui de "choix" (je met que le passage en question, les fonctions et autres blabla sont pas utiles)
pour ce qui est des printf un peu partout, vu que débug du multiprocess avec GDB c'est pas trivial, j'ai foutu des printf un peu partout pour debug à la main !
Une dernière chose avant de regarder le vif du sujet : les ipcs sont créées par un processus a part, voila pourquoi ces 2 processus ne font que s'attacher aux différentes IPCs dont ils ont besoin
 
J'ai mis en gras le passage où le 1er processus se bloque en attente (ou bien renvoi -1 avec IPC_NOWAIT) mais je laisse les déclarations de variables au cas où il y aurait besoin.

CODE.C
 
 57 int main()
 58 {
 59   int PIDchoix,t,sem_compteur,sem_phrase,sem_lettre,BAL,numeroPhrase,lettreCodage;
 60   char phrase[65];
 61   char conditionArret[]="stop";
 62   char conditionArret2[]="STOP";
 63   struct msgbuf
 64   {
 65     long mtype;
 66     char mtext[65];
 67   }message;
 68   message.mtype=1;
 69  
 70   signal(SIGUSR1,signal_ignore);                      /* deviation du signal              */
 71  
 72   //sem_compteur=semget(cle_compteur,1,0);            /* attachement semaphore compteur   */
 73   sem_phrase = semget(cle_phrase,1,0);                /* attachement semaphore phrase     */
 74   sem_lettre = semget(cle_lettre,1,0);                /* attachement semaphore lettre     */
 75   t = open("TUBE",O_RDONLY);                          /* attachement au tube nomme        */
 76   BAL = msgget(cle_BAL,0666);                         /* attachement a la boite au lettre */
 77  
 78   //up(sem_compteur);                                 /* incrementation du compteur       */
 79  
 80   //echange PID
 81   printf("debut echange PID\n" );
 82   sprintf(message.mtext,"%d", getpid());
 83   printf("%s est mon PID\n",message.mtext);
 84  if((msgsnd(BAL,&message,sizeof(message.mtext),0))==-1)
 85     printf("ERREUR ENVOI PID" );
 86   printf("PID envoye\n" );
87   if((msgrcv(BAL,&message,100,2,IPC_NOWAIT))==-1)
 88     printf("ERREUR RECEPTION PID\n" );

 91   printf("%s est le PIDchoix\n",message.mtext);
 92   PIDchoix=atoi(message.mtext);
 93   printf("fin echange PID\n\n" );
 94   //fin echange PID

voila le bout de code du processus faisant l'échange de PID (chez lui aucun prob, il recoit et envoi son message sans m'afficher aucun message d'erreur) :

 
CHOIX.C
 
 27 int main()
 28 {
 29   int sem_compteur,sem_lettre,sem_phrase,BAL,PIDcode,numeroPhrase,lettreCode;
 30   char conditionArret[]="stop";
 31   struct msgbuf
 32   {
 33     long mtype;
 34     char mtext[65];
 35   }message;
 36   message.mtype=2;                                /* choix : message de type 2      */
 37  
 38   srand(time(NULL));                              /* initialisation compteur random */
 39   signal(SIGUSR1,signal_ignore);                  /* deviation du signal SIGUSR1    */
 40   //sem_compteur=semget(cle_compteur,0666);       /* attachement semaphore compteur */
 41   sem_lettre = semget(cle_lettre,1,0);            /* attachement semaphore lettre   */
 42   sem_phrase = semget(cle_phrase,1,0);            /* attachement semaphore phrase   */
 43   BAL=msgget(cle_BAL,0666);                       /* attachement boite au lettres   */
 44  
 45   //semop(...&up(sem_compteur));                  /* incrémentation compteur        */
 46  
 47  
 48   /*  echange PID     */
 49   printf("debut echange PID\n" );
 50   msgrcv(BAL,&message,100,1,0);
 51   printf("%s est le PID de code\n",message.mtext);
 52   PIDcode=atoi(message.mtext);
 53   printf("PID recu\n" );
 54   sprintf(message.mtext,"%d",getpid());
 55   printf("%s est mon PID\n",message.mtext);
 56   //if((msgsnd(BAL,&message,sizeof(message.mtext),0))==-1)
 57     //printf("ERREUR ENVOI" );
 58   printf("FIN echange PID\n" );
 59   /*  fin echange PID */
 

 
Merci encore de votre aide, si qqun arrive à comprendre, ça pourrait bien m'aider pcq là ... je sèche totalement ...

Reply

Marsh Posté le 13-01-2010 à 00:04:32    

Ton controle d'erreur ne sert a rien dans la mesure ou il ne te renseigne pas sur le pourquoi de l'erreur!
D'apres la manpage de msgrcv ( http://man.cx/msgrcv%282%29/fr ) :

Citation :

 
      En cas d'chec de msgrcv(), errno prend l'une des valeurs suivantes :
 
       E2BIG  Le  message  est  plus  long que msgsz, et MSG_NOERROR n'a pas t
              indiqu dans msgflg.
 
       EACCES Le processus appelant n'a pas de permission de lecture  dans  la
              file et n'a pas la capacit CAP_IPC_OWNER.
 
       EAGAIN Aucun  message  n'est disponible dans la file, et IPC_NOWAIT est
              spcifi dans msgflg.
 
       EFAULT msgp pointe en dehors de l'espace d'adressage accessible.
 
       EIDRM  La file  de  messages  a  t  supprime  alors  que  le  processus
              attendait un message.
 
       EINTR  Un  signal  est  arriv  avant d'avoir pu lire quoi que ce soit ;
              voir signal(7).
 
       EINVAL msgqid ou msgsz invalides.
 
       ENOMSG IPC_NOWAIT a t requis dans msgflg et aucun message du type rclam
              n'existe dans la file.
 


 
Je crois que ton erreur c'est que dans choix, tu init message.mtype=2; puis tu passe l'adresse de message pour recevoir (donc le mtype est ecrasé! ie mtype=1)
Reinitialise message.mtype avant l'envoi du message dans choix!

Reply

Marsh Posté le 13-01-2010 à 00:15:49    

Problème résolu !!!! tu avais raison, le mtype était bien écrasé à cause du msgrcv.
Je n'aurai jms pensé que le type allait être écrasé. Mais ça semble super logique quand on y pense !
 
Merci de m'avoir donné un peu de ton temps :) tu m'as clairement évité encore plusieurs heures de recherches !
 
Encore merci :bounce:


Message édité par lambou le 13-01-2010 à 00:16:24
Reply

Marsh Posté le 13-01-2010 à 10:36:10    

lambou a écrit :


 
 63   struct msgbuf
 64   {
 65     long mtype;
 66     char mtext[65];
 67   }message;
 68   message.mtype=1;
...
 84  if((msgsnd(BAL,&message,sizeof(message.mtext),0))==-1)
 85     printf("ERREUR ENVOI PID" );
 86   printf("PID envoye\n" );
87   if((msgrcv(BAL,&message,100,2,IPC_NOWAIT))==-1)
 88     printf("ERREUR RECEPTION PID\n" );

[/i]

 
CHOIX.C
 31   struct msgbuf
 32   {
 33     long mtype;
 34     char mtext[65];
 35   }message;
 36   message.mtype=2;                                /* choix : message de type 2      */
...
 50   msgrcv(BAL,&message,100,1,0);
 51   printf("%s est le PID de code\n",message.mtext);



 
Bonjour,
Encore 2/3 petites choses (avis perso):
1- pour limiter ce genre d'erreur a l'avenir, rapproche autant que possible l'initialisation d'une variable avec son utilisation, dans ce cas ci juste avant l'envoi d'un message c'est mieux
2- la longueur de "message" n'est pas de 100 (dans ton msgrcv!), là tu dis à msgrcv qu'il peut ecrire pour 100 octets dans message alors que la structure en compte moins -> source de bug possible!
3- marque davantage la mise en page en utilisant la tabulation pour indenter ton code au lieu d'un ou deux espace, cela mettra davantage en évidence sa structure
4- essaie d'améliorer un peu le controle d'erreur (je sais, c'est fastidieux!)( voir un de mes posts ci dessus)
5- le forum propose une balise [ code ] pour insérer du code source avec mise en évidence de la syntaxe, plus lisible sur un forum

Reply

Marsh Posté le 14-01-2010 à 15:27:08    

le programme est maintenant 100% fonctionnel :)  
Je peux m'attaquer à mon 2e TP :(
 
merci encore pour tous ces conseils :)

Reply

Marsh Posté le 14-01-2010 à 15:27:08   

Reply

Marsh Posté le 15-01-2010 à 18:54:13    

Bon courage!

Reply

Marsh Posté le 16-01-2010 à 17:40:37    

Passe le bonjour à IBL de ma part hihi :D

Reply

Marsh Posté le 16-01-2010 à 17:42:48    

ahaha un connaisseur :D  
t'es de quelle promo ??
 

Reply

Marsh Posté le 16-01-2010 à 17:44:12    

2008 :)
 
J'ai reconnu à la gueule du TP puis qd tu dis télécoms et qd je vois lyon sur ton profil j'avais peu de chance de me tromper :D

Reply

Marsh Posté le 16-01-2010 à 17:46:56    

visiblement les profs s'embetent pas, ils nous refourguent les même TPs !
C'est marrant je pensais pas trouver un INSA TC sur ce forum ^^ le monde est petit !
espérons qu'IBL n'y fasse pas un tour ! xD


Message édité par lambou le 16-01-2010 à 17:47:23
Reply

Marsh Posté le 16-01-2010 à 17:47:26    

On est quelque uns ;)

Reply

Marsh Posté le 16-01-2010 à 17:49:40    

tant mieux, la prochaine fois que je suis en galère je sais à qui m'adresser :D
 
 

Reply

Marsh Posté le 16-01-2010 à 17:56:38    

Oups :D

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed