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 :

Problèmes de FIFO


Sujet :

Linux

  1. #1
    Membre averti
    Inscrit en
    Juillet 2009
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 35
    Par défaut Problèmes de FIFO
    Bonjour,

    J'ai un petit problème avec les FIFOs, dont j'ai du mal à comprendre le fonctionnement... ou tout du moins à utiliser leur fonctionnement. Je m'explique.

    J'ai 2 applications A et B qui ont besoin de communiquer. Pour cela, j'ai mis en place 2 FIFOs, une A>B (F1) et une B>A (F2). J'ai pas de problème pour ouvrir les FIFOs, mais c'est dans la communication que les problèmes apparaissent.

    A envoie une commande sur F1 et attend une réponse sur F2. Problème, de son côté, B ne reçoit rien sur F1 ! Du coup, B est bloquée en attendant une commande, et A en attendant une réponse.... Au bout d'un moment, j'arrête A, pour voir ce qui ne va pas. Et je constate qu'à ce moment précis, B accède aux données que A avait envoyées dans F1.

    Avez-vous une idée d'où pourrait venir le problème ?

    Merci de m'avoir lu !

  2. #2
    Expert confirmé Avatar de frp31
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2006
    Messages
    5 196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5 196
    Par défaut
    là comme ça moi non plus j'ai rien compris à ton besoin....

    un fifo c'est first in first out unidirectionnel
    donc a -> b et APRES tu peux faire dans l'autre sens mais pas en même temps.

  3. #3
    Expert confirmé Avatar de frp31
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2006
    Messages
    5 196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5 196
    Par défaut
    là comme ça moi non plus j'ai rien compris à ton besoin....

    un fifo c'est first in first out unidirectionnel
    donc a -> b et APRES tu peux faire dans l'autre sens mais pas en même temps.

    sauf à passer par des moyens détournés ....mais dans ce cas la le fifo devient une mauvaise solution et un socket et plus approprié. par exemple

  4. #4
    Membre averti
    Inscrit en
    Juillet 2009
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 35
    Par défaut
    Bonjour !

    Tout d'abord merci de te pencher sur mon problème !

    Effectivement, les FIFOs sont unidirectionnelles. C'est la raison pour laquelle j'en ai deux ! Sur la première FIFO, A envoie des commandes à B. Sur la seconde FIFO, B renvoie le résultat des commandes.

  5. #5
    Expert confirmé Avatar de frp31
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2006
    Messages
    5 196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5 196
    Par défaut
    mais c'est pas possible ça, puisque tant que la liaison est ouverte dans 1 sens, tu peux pas en avoir une en // dans le sens inverse.

  6. #6
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Montre nous ton code.

  7. #7
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    J'aimerai bien savoir qui s'amuse à mettre des -1 sans raison. Pas juste dans ce sujet, mais dans d'autres aussi. Parfois même sur le premier post d'un sujet, qui pourtant pose une question légitime et relativement bien rédigée. On en voit de plus en plus et ça a le don de m'énerver.

  8. #8
    Membre averti
    Inscrit en
    Juillet 2009
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 35
    Par défaut
    Voilà les parties du code relatives aux FIFOs. Le premier programme est en Python, le second est en C/C++. "fcmd" et "fdata" sont les noms des deux fifos, que j'ai créées en utilisant la commande "mkfifo --mode=a+rw"


    Application "client" :
    Code Python : 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
    class client:
     
    	def send(command):
    		self.cmd_fifo.write(command)
     
    	def receive():
    		data=""
    		while data=="":
    			data=self.data_fifo.readline()
    			time.sleep(1)
    		return data
     
    	def run():
    		self.cmd_fifo=open("./fcmd","w")
    		self.data_fifo=open("./fdata","r")
     
    		self.send("ma_commande")
    		data = self.receive()
    Application "serveur" :
    Code C/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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    char* execute(char* command);
     
    void read_cmd(char* buf,int buf_size, FILE* fifo) {
    	char c=0;
    	int it=0;
     
    	while((c=fgetc(fifo))==EOF) {
    		sleep(1);
    	}
     
    	do {
    		buf[it]=c;
    		it++;
    	} while(it<buf_size && (c=fgetc(fifo))!=EOF);
    }
     
    void send_data(char* data,int data_size, FILE* fifo) {
    	int it=0;
    	for(it=0;it<data_size;it++) {
    		fwrite(&buf[i],sizeof(char),1,fifo);
    	}
    }
     
    int main(argc, char* argv[]) {
    	FILE* cmd_fifo = fopen("./fcmd","r");
    	FILE* data_fifo = fopen("./fdata","w");
    	char cmd[100];
    	char data[100];
     
    	if(cmd_fifo==NULL || data_fifo==NULL) {
    		fprintf(stderr,"FIFO error\n");
    		exit(-1);
    	}
     
    	while(1) {
    		memset(cmd,0,100);
    		memset(data,0,100);
    		read_cmd(cmd,100,cmd_fifo);
    		data=execute(cmd);
    		send_data(data,100,data_fifo);
    	}
     
    	return 0;
    }

    Désolé si je ne mets pas le code original, le projet est assez confidentiel...

    Les deux applications se bloquent dans leur fonction de réception de donnée. La première considère avoir envoyé ses données et attend la réponse, tandis que la seconde reste en attente de la commande, qu'elle semble n'avoir pas reçue. Lorsqu'on tue manuellement l'application cliente, l'application serveur reçoit alors la commande et la traite correctement.

    Cela pourrait bien s'expliquer si la lecture était bloquée par une ouverture en écriture, mais je n'ai lu nulle part que c'était le cas. Des avis ?

    J'espère avoir été clair, et si jamais vous avez besoin d'informations supplémentaires, je reste à l'écoute ! Merci encore

  9. #9
    Membre averti
    Inscrit en
    Juillet 2009
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 35
    Par défaut
    Citation Envoyé par frp31 Voir le message
    mais c'est pas possible ça, puisque tant que la liaison est ouverte dans 1 sens, tu peux pas en avoir une en // dans le sens inverse.
    Que veux-tu dire ? Que Linux n'est pas prévu pour l'utilisation de 2 FIFOS en même temps ? Il s'agit de 2 FIFOs différentes, avec chacune un sens dédié. Je vois a priori pas où est le problème avec une telle architecture...

  10. #10
    Expert confirmé Avatar de frp31
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2006
    Messages
    5 196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5 196
    Par défaut
    aucun OS ne permet jamais ça le fifo reste tjrs quoi qu'il arrive unidirectionnel d'objet à objet ..... on peut en faire autant qu'on veut mais si deux ou plus sont sur les memes sources/destination ça marche pas... c'est pourquoi la méthode est mauvaise (après reflection) la solution :
    il faut refaire les codes pour utiliser un socket

  11. #11
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    On peut tout à fait utiliser deux fifo (pipe ou fichier fifo) pour communiquer bidirectionnellement entre deux processus.

    Ca ressemble à un problème de bufferisation. Essaie d'ajouter un self.cmd_fifo.flush() (je ne connais pas python mais tu vois l'idée) après le write() dans ton send(), et un fflush(fifo) après le write() dans ton send_data().

    Une autre solution pour éviter d'avoir à flusher explicitement les streams après les write() est de les passer en mode non bufferisé. En C tu fais un setbuf(stream, NULL). En python apparemment tu peux ajouter l'argument 0 au open() pour demander un buffer de taille nulle.

  12. #12
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Aussi, dans read_cmd(), la boucle sur le sleep(1) ne sert à rien. De toute façon le fgetc() bloquera tant que personne n'aura écrit dans le fichier.

  13. #13
    Membre averti
    Inscrit en
    Juillet 2009
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 35
    Par défaut
    Je vous remercie pour vos conseils. La mise en place des flsuh n'a rien changé cependant... Ce qui m'amène, à nouveau dans l'impasse...

    Du coup je passerais bien aux sockets, mais je n'y connais rien. Pouvez-vous me suggérer des tutos/cours/docs pour que j'y parvienne rapidement ?

  14. #14
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    En fait en regardant ton code d'un peu plus près je pense que ton problème c'est simplement que tu ne fermes pas self.cmd_fifo après le write(). Du coup le fread() du serveur ne retourne jamais EOF. Et même chose dans l'autre sens, le serveur doit fermer data_fifo après avoir écrit ses données.

Discussions similaires

  1. problème de fifo et de goto
    Par bellevue dans le forum Débuter
    Réponses: 13
    Dernier message: 10/06/2010, 16h31
  2. Problème avec les tubes fifo
    Par Fate_B dans le forum C
    Réponses: 1
    Dernier message: 05/04/2010, 17h37
  3. problème de fifo bloquant sous linux
    Par Fonzy007 dans le forum POSIX
    Réponses: 6
    Dernier message: 20/05/2009, 09h44
  4. Linux - problème avec fifos (communication IPC)
    Par wiliwiliwili dans le forum Linux
    Réponses: 4
    Dernier message: 27/08/2007, 22h18
  5. Problème de Queue FIFO
    Par Armando dans le forum C++
    Réponses: 3
    Dernier message: 05/12/2006, 00h01

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