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

POSIX C Discussion :

Probleme comprehension pipe


Sujet :

POSIX C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Février 2007
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 11
    Par défaut Probleme comprehension pipe
    Bonjour,

    On a eu un exercice:
    * Écrire les programmes addition, multiplication, soustraction. Utiliser scanf pour lire les nombres, printf pour les afficher (en clair: faire simple, rapide, concis)
    * Écrire le programme dispatch, qui doit commencer par lancer les co-processus, puis attend sur l'entrée standard un ordre du style "addition 2 4". Avec strcmp, trouver quel est le co-processus à utiliser, lui envoyer l'ordre, puis afficher le résultat.


    J'ai réussi a faire fonctionner le programme mais il y a des zones d'ombres, et j'aimerais savoir pourquoi est-ce que ca marche.

    Voila le code de dispatch.
    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
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
     
    int main(int argc, char ** argv)
    {
     
    int pid=0;
     
    int add[2];
    int sous[2];
    int mult[2];
     
    char commande[500]="";
    int nb1=0;
    int nb2=0;
     
    pipe(add);
    pipe(sous);
    pipe(mult);
     
     
     
     
    pid=fork();
    	if(pid==0)
    	{
     
    	dup2(add[0],0);
    	close(add[1]);
    	 execvp("add",NULL);
    	printf("Si add, a raté \n");
     	return EXIT_FAILURE;
    	}
     
     
    pid=fork();
    	if(pid==0)
    	{
    	 dup2(sous[0],0);
    	close(sous[1]); 
    	execvp("sous",NULL);
    	 printf("Si sous, a raté \n");
     	return EXIT_FAILURE;
    	}
     
     
    pid=fork();
    	if(pid==0)
    	{
    	 dup2(mult[0],0);
    	close(mult[1]);
    	 execvp("mult",NULL);
     	 return EXIT_FAILURE;	
    	}
     
     
    puts("");
    while(1){
     
     
    close (add[0]);
    close (sous[0]);
    close (mult[0]);
     
    scanf("%s %d %d",commande,&nb1,&nb2);
     
    	if(strcmp(commande,"add")==0){
    		dup2(add[1],1);
    		printf("%d\n",nb1);
    		printf("%d\n",nb2);
     
     
    	}
     
    	else if(strcmp(commande,"sous")==0){
    		dup2(sous[1],1);
    		printf("%d\n",nb1);
    		printf("%d\n",nb2);
     
    	}
     
    	else if(strcmp(commande,"mult")==0){
    		dup2(mult[1],1);
    		printf("%d\n",nb1);
    		printf("%d\n",nb2);
     
    	}
     
    }
     
     
    return 0;
     
    }


    Et le code de add :

    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
     
    #include <stdio.h>
    #include <unistd.h>
     
    int main(void){
     
    int a=0,b=0; 
    while(1){
    scanf("%d",&a);
    scanf("%d",&b);
     
    printf("resultat =%d\n",a+b);
     
    }
    return 0;
    }

    Si vous regardez le code du dispatch, juste avant le while(1) j'ai mis un puts(""); et le problème, quand je l'enlève ce puts, quand je tape add 4 5 par exemple, il ne se passe rien du tout, j'ai l'impression qu'il n'y a aucune communication, et quand le je met, ça marche comme il faut, si quelqu'un pouvait m'expliquer pourquoi (ou si j'ai fait une grossière erreur) j'aimerais le savoir.

    Merci d'avance pour vos réponses.

    Edit: Je vous l'accorde c'est un peu sale, aucune vérification d'erreur :p.

  2. #2
    Membre confirmé
    Homme Profil pro
    Software engineer
    Inscrit en
    Août 2008
    Messages
    139
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Software engineer

    Informations forums :
    Inscription : Août 2008
    Messages : 139
    Par défaut
    juste une idée :
    peu etre c'est une question du tampon de l'entrée ou la sortie standard, remplace puts("") par fflush(stdin) ou/et fflush(stdout) et essaie de voir ce que ça donne !

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    fflush(stdin) est un bug, merci de ne pas donner de mauvaises idées aux gens.

    Je ne comprends pas pourquoi ça ne marcherait pas sans le puts(): vu que les chiffres sont bien suivis d'un saut de ligne, ça ne devrait pas trop bloquer.
    Mais peut-être que les tubes ne flushent pas automatiquement sur un \n, donc mettre un fflush(stdout) après l'écriture des nombres peut être une bonne idée.

    PS: De grâce, évite d'utiliser des nombres quand tu fais tes dup2(). La constante STDOUT_FILENO est là pour ça...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Je ne comprends pas pourquoi ça ne marcherait pas sans le puts(): vu que les chiffres sont bien suivis d'un saut de ligne, ça ne devrait pas trop bloquer.
    De memoire, la norme C demande que les devices interactifs soient bufferises par lignes, les autres par blocs; Posix definit uniquement les terminaux comme device interactifs.

    Donc flush() apres ecriture si on veut etre sur que ca part.

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    De memoire, la norme C demande que les devices interactifs soient bufferises par lignes, les autres par blocs; Posix definit uniquement les terminaux comme device interactifs.

    Donc flush() apres ecriture si on veut etre sur que ca part.
    Je trouve que c'est mauvais, vu qu'un programme lancé avec popen() ne s'attend pas forcément à ça. Cela oblige à concevoir les programmes de façon à ce qu'ils flushent systématiquement leur sortie standard manuellement avant de se mettre en attente d'entrée...

    La bonne nouvelle, c'est que ce problème dans POSIX rend compliante l'implémentation Windows des pipes.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Je trouve que c'est mauvais, vu qu'un programme lancé avec popen() ne s'attend pas forcément à ça. Cela oblige à concevoir les programmes de façon à ce qu'ils flushent systématiquement leur sortie standard manuellement avant de se mettre en attente d'entrée...
    popen ne permet pas du bidirectionnel, donc pour simuler un utilisateur, c'est un peu complique avec ca.

    Un programme qui veut simuler un utilisateur pour un autre programme interactif doit passer par les pseudo terminaux. Si tu veux scripter, voir expect().

Discussions similaires

  1. Probleme comprehension du passage par reference
    Par rookie1 dans le forum Débuter
    Réponses: 4
    Dernier message: 01/02/2009, 19h55
  2. Probleme comprehension Mysql & c++
    Par cluigi dans le forum C++
    Réponses: 0
    Dernier message: 02/12/2007, 22h59
  3. Probleme comprehension Mysql & c++
    Par cluigi dans le forum C++
    Réponses: 0
    Dernier message: 02/12/2007, 17h59
  4. [C++.NET] Probleme comprehension de code
    Par raboin dans le forum VC++ .NET
    Réponses: 3
    Dernier message: 03/05/2006, 12h49
  5. [THREAD] probleme de pipe
    Par mehdiyassin dans le forum Concurrence et multi-thread
    Réponses: 5
    Dernier message: 01/07/2004, 13h50

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