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

Linux Discussion :

probleme file IPC


Sujet :

Linux

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mai 2008
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 29
    Par défaut probleme file IPC
    Hello,

    pour un projet, je dois synchroniser des processus. Pour cela, j'utilise des IPC pour qu'il echange aussi quelques informations. Seulement, je sais pas pkoi, j'ai un souci sur un file IPC, alors qu'une autre du projet fonctionne.

    Dans le main.c j'ai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if(( msgid = msgget(cle,IPC_CREAT | IPC_EXCL | 0777)) == -1){
            erreurFin("Pb msgget !");
        }
    sprintf(cmd,"gnome-terminal -e \"./controlleur %s\";",nomProjet);
    system(cmd);
    La cle est definie par un define (pour etre sur que le prob ne vient pas de la).

    Dans le controlleur.c j'ai :

    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
     
    typedef struct{
    	pid_t pidEmetteur;
    	int acces;
    	long type;
    	char nomFichier[TAILLE_MAX_FICHIER];
    }trequeteControlleur;
    int main(){
       if( ( msgid = msgget(cle,0)) == -1){
            printf("Pb msgget !");
        }
      //....////
      while(1){
    		printf("En attente d'une requete \n");
     
    		msgrcv(msgid,&req,tailleReq,2,0);
     
    		printf("Lecture de requete de type : %d \n",req.acces);
                    char commande[200];
    		char nomJournal[28];
    		printf("on cree une reponse pr la demande de creation de document\n");
    		sprintf(nomJournal,"%sjournal",nomFichier);
    		sprintf(commande,"touch ./%s/fichier/%s; touch ./%s/fichier/%s;",nomProjet,nomFichier,nomProjet,nomJournal);
    		system(commande);
     
    		sprintf(commande,"echo %s >> %s/fichier/ListeFichier.txt",nomFichier,nomProjet);
    		system(commande);
     
    		tabDocument[num] = 1;	
     
    		rep->numSem = num;
    		rep->type = (long)pidE;
     
                   msgsnd(msgid,&rep,tailleRep,0);
      }
    }
    Le role du controlleur.c est de traiter les requetes des autres processus et de leur fournir une reponse en fonction de ce qu'ils demandent.

    La procedure qui se sert qui envoie une requete :
    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
    void creationDocument(){
    	char nomFichier[TAILLE_MAX_FICHIER];
     
     
    	trequeteControlleur req;
    	treponseControlleur rep;
     
    	int tailleReq, tailleRep;
     
    	tailleReq = sizeof(trequeteControlleur) - sizeof(long);
    	tailleRep = sizeof(treponseControlleur) - sizeof(long);
     
    	printf("Quel est le nom du fichier à ajouter :");
    	scanf( "%s", nomFichier );
     
    	req.type = 2;
    	req.pidEmetteur = getpid();
    	sprintf(req.nomFichier,"%s",nomFichier);
    	req.acces = 1;
     
     
    	printf("demande de creation\n");
    	msgsnd(msgid,&req,tailleReq,0);	
    	printf("attente de reponse\n");
    	msgrcv(msgid,&rep,tailleRep,(int)getpid(),0);
    	printf("reponse semaphore %d \n",rep.numSem);
     
    }
    Cette procedure est dans le main.c. Elle connait donc msgid et les structures sont bien defini et identique a controlleur.c

    Lorsque je teste mon programme, la procedure creationDocument recoit une reponse alors que le controlleur ne recoit pas la requete. Je ne sais pas si le fait que je lance mon controlleur en faisant un gnome-terminal -e change qqch a l'histoire ou si l'erreur vient d'ailleurs. Les flags de msgsnd et msgrcv ? Je galere sur ce prob depuis 2jours sans trouver de reponse.

    PS : je suis sur opensolaris.

    Merci a tous ceux qui se penchent sur mon cas ^^.

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    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 840
    Billets dans le blog
    1
    Par défaut
    Tes 2 autres codes "controleur.c" et "creationDocument" utilisent msgid pour attaquer leur msq. Mais msgid doit avoir été rempli par msgget(). Je veux bien que creationDocument() étant dans le main.c, la variable msgid soit connue (ça ressemble à une variable globale ce qui est sale mais on va passer ce détail). Mais dans "controleur.c" qui est un programme annexe, là faut qu'il ouvre lui aussi sa msq via msgget(). Je me demande d'ailleurs pourquoi tu appelles controleur.c via system() et non sous forme de fonction...

    PS: Pour créer mes clef j'utilise ftok(). En jouant astucieusement avec les paramètres et les infos que je peux avoir provenant de mon environnement (getuid(), ".", argv[0], etc...) je peux créer des clefs uniques, uniques mais dépendant de l'utilisateur, uniques mais dépendant du répertoire où on se trouve, etc en fonction du besoin.
    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]

  3. #3
    Membre averti
    Inscrit en
    Mai 2008
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 29
    Par défaut
    Merci pour ta reponse.

    Effectivement, je dois utiliser msgget dans mon controlleur.c. Dans mon fichier msgget etait present j'ai oublie de le rajouter. J'edite le code en haut.

    Le probleme vient donc d'ailleurs.

    Par contre, tu m'as fait d'autres remarques.

    Pour la variable globale, j'avais deja lu que c'etait pas bien de procede ainsi, seulement, je ne vois pas comment faire autrement. Pourrais tu me dire comment eviter d'utiliser un msgid en global.

    Ensuite, pour la commade system. Comment je pourrais faire d'autres ? Je dirais bien avec un fork, mais a part allourdir le code, je ne vois pas l'interet. Est-ce que tu pourrais developper stp ?

    Aussi, tu me dis que je pourrais utiliser une fonction controlleur au lieu d'un nouveau fichier. Dans ce cas la, je devrais faire une fonction de ce type la ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void monfork( void (*pauBoulot) ())
      {
     
         if (fork()==0) {
            (*pauBoulot) ();
            exit(0);         /*assure terminaison du fils*/
            }
      }
    monfork(controlleur);

    Pour la generation de la clef, j'avais prevu d'utiliser ftok, ms je voulais deja faire marcher mon programme avec un bon vieux define pour etre sur que c'est pas ce qui pose probleme.

    Desole pour toutes ces question de "base", mais j'ai pas trop l'habitude de coder en C. Mais ca vient tout doucement ^^ (enfin j'espere)

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    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 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par versus68 Voir le message
    Pour la variable globale, j'avais deja lu que c'etait pas bien de procede ainsi, seulement, je ne vois pas comment faire autrement. Pourrais tu me dire comment eviter d'utiliser un msgid en global.
    Tu passes msgid en paramètre à la fonction. Ou ta fonction rappelle msgget() au choix

    Citation Envoyé par versus68 Voir le message
    Ensuite, pour la commade system. Comment je pourrais faire d'autres ? Je dirais bien avec un fork, mais a part allourdir le code, je ne vois pas l'interet. Est-ce que tu pourrais developper stp ?
    Ben system() sert à appeler un programme externe et attend la fin avant de rendre la main à l'instruction suivante. Ce n'est donc pas une exécution en parallèle.
    Ainsi donc si ce programme appelé n'a qu'une action, tu mets simplement l'action dans une fonction et tu appelles la fonction.

    Citation Envoyé par versus68 Voir le message
    Aussi, tu me dis que je pourrais utiliser une fonction controlleur au lieu d'un nouveau fichier. Dans ce cas la, je devrais faire une fonction de ce type la ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void monfork( void (*pauBoulot) ())
      {
     
         if (fork()==0) {
            (*pauBoulot) ();
            exit(0);         /*assure terminaison du fils*/
            }
      }
    monfork(controlleur);
    Si le contrôleur doit tourner en parallèle c'est effectivement un moyen mais comme ça ne semble pas être le cas...

    Citation Envoyé par versus68 Voir le message
    Pour la generation de la clef, j'avais prevu d'utiliser ftok, ms je voulais deja faire marcher mon programme avec un bon vieux define pour etre sur que c'est pas ce qui pose probleme.
    Ok - J'ai vu autre chose qui me gène => dans msgrcv(), ton 3° paramètre est "taillereq". Cette valeur indique la taille maximale autorisée à être récupérée par la fonction. c.a.d que s'il y a un message de 20 octets mais que tu écris 10, tu recevras les 10 premiers octets mais le message sera quand-même effacé de la file.
    Et donc je ne vois pas l'initialisation de cette valeur "taillereq"...?

    Autre chose: personnellement, je définis un type "info" destiné à contenir mon message (une structure qui ne contient que les valeurs du message) et un type "enveloppe" destiné à contenir le type du message et ses data
    Exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    typedef struct {
       ...
       ...
       ...
    } t_msgInfo;
     
    typedef struct {
        long numOrdre;
        t_msgInfo info;
    } t_msgEnveloppe;
    Ainsi, je sépare l'enveloppe de son contenu. Et quand j'appelle msgsnd, je passe en 1° paramètre l'adresse d'un t_msgEnveloppe et en 3° paramètre sizeof(t_msgInfo) ce qui m'évite de jongler en enlevant la zone du numOrdre. Bon j'ai jamais compris pourquoi ce 3° paramètre devait être la taille complète moins la taille du num (la fonction pourrait faire la soustraction elle-même) mais avec cette méthode, ça devient plus lisible...
    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]

  5. #5
    Membre averti
    Inscrit en
    Mai 2008
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 29
    Par défaut
    Mon controlleur doit bien s'exécuté en parrallèle. Je vais changer le system pour le fork.

    On m'a trouvé l'erreur de mon problème... C'était bète, mais c'est à savoir !
    En fait, le premier attribut de la structure que l'on veut envoyer doit être le "long type".... !! A priori, c'est impératif. J'ai changé, maintenant ça marche !

    Je te remercie (beaucoup) pour tes conseils, ça va m'aider à améliorer mon code !

    PS : j'avais bien initialisé tailleReq, c'est juste que j'ai oublié de le copier/coller dans le post.

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    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 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par versus68 Voir le message
    On m'a trouvé l'erreur de mon problème... C'était bète, mais c'est à savoir !
    En fait, le premier attribut de la structure que l'on veut envoyer doit être le "long type".... !! A priori, c'est impératif. J'ai changé, maintenant ça marche !
    Tiens ? C'est vrai. Moi je l'ai mis en premier dans ma structure enveloppe par habitude mais j'ai pas fait gaffe que tu l'avais pas fait.
    En y réfléchissant, c'est normal. La fonction récupère un type donc faut qu'elle sache où le prendre. C'est là qu'on voit l'utilité de séparer les data de son message des éléments de travail de la msq...
    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. Probleme File.delete en ruby
    Par socorem dans le forum Langages de programmation
    Réponses: 0
    Dernier message: 02/06/2009, 13h50
  2. [Profiler gprof.exe]Probleme : File has no symbols.
    Par HugoBrac dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 15/04/2009, 21h11
  3. probleme file de message
    Par allezlolo dans le forum Débuter
    Réponses: 2
    Dernier message: 19/12/2008, 16h27
  4. Probleme file de message
    Par Treuze dans le forum C
    Réponses: 3
    Dernier message: 13/06/2006, 20h02
  5. [Debutant]Probleme file de message
    Par Treuze dans le forum C
    Réponses: 11
    Dernier message: 15/05/2006, 21h46

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