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

C++ Discussion :

Synchronisation procesus lectures/ecritures tubes


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Inscrit en
    Janvier 2004
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 10
    Par défaut Synchronisation procesus lectures/ecritures tubes
    Salut!

    J'ai un peu de mal à capter comment les tubes fonctionnent à cause des résultats aléatoires que je récupère... Je vous explique.

    J'ai pour mission de récupérer la liste des fichiers d'un sous arbre à partir d'un point donné du disque.

    Exemple : ./monprog repdepart

    Lors du parcours de repdepart, le programme va, s'il tombe sur un repertoire à l'interieur de repdepart, lancer un processus fils avec l'appel fork();.

    Les processus communiquent entre eux la liste des fichiers trouvés via UN tube.

    Donc, le tube est crée par le programme principal. Premier fork() : si je suis le fils, je ferme le tube en lecture et je lance l'algoryhtme sur (repdepart,tube).
    Si je suis le pere, je ferme le tube en ecriture et j'attends par un while (read ...) des informations de mon fiston.

    Maintenant, si le fils, lorsqu'il parcoure la liste des fichiers, trouve un repertoire, il crée un fils avec (repdepart/reptrouvé,tube);

    Ainsi de suite.

    Le probleme est que quand le premier fils a fini son boulot, le pere considère que il n'y aura plus rien dans le tube et termine la boucle while(read...)

    J'ai bien essayé de placer quelques wait(0);, avant la fermeture des tubes en ecriture par les fils (donc quand il ont fini) ou à d'autres endroits, ca ne marche pas.

    Donc j'aimerais qu'on m'explique quelques trucs quand à ces histoires de tubes et fork. Parceque je comprends pas pourquoi le pere arrete de lire alors que l'un de ses sous fils a toujours un tube ouvert en mode ecriture.

    L'algoryhtme en simplifié :

    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
     
     
    #include<iostream.h>
    #include"Liste.h"
    #include <stdio.h>
    #include <sys/types.h>
    #include <dirent.h>
    #include <sys/wait.h>
    #include <fstream.h>
    #include <sys/stat.h>
     
     
    void parcours(char * repertoire, int * tube)
    {
    	cout<<"("<<getpid()<<")" << "Fonction parcours sur : " << repertoire << endl;
    	char cheminfich [1024];
    	char liste[2048];
     
    	close(tube[0]);
     
    	struct dirent *lecture;
    	DIR *rep;
    	pid_t pid;
    	rep = opendir(repertoire);
     
    	struct stat st;
     
       if (rep) {
    	while (lecture = readdir(rep))
    	{
    		//si c'est un fichier régulier, je l'ajoute à ma liste de fichiers spéaré par un caractere disons '|'
     
    			//sinon si c'est un repertoire, je lance un fils
    			{
    				pid=fork();
    				if (pid==0) {
    					parcours(cheminfich,tube); //cheminfich a déjà ete modifié et contiens bien le chemin vers le repertoire que l'on viens de trouver
    				}
    			}
    		}
    	}
     
    	write(tube[1],liste,strlen(liste)+1);
     	closedir(rep);
      }
     
    	close(tube[1]);
    }
     
     
    int main (int argc, char * argv[])
    {
    	int tube[2];
    	char buffer[1024];
    	pid_t pid;
     
    	if (argc!=2)
    	{
    		cout<<"("<<getpid()<<")"<<"Spécifiez un et un seul repertoire à analyser."<<endl;
    		exit(-1);
    	}
     
    	if (pipe(tube)<0)
    	{
    		cout<<"("<<getpid()<<")"<<"Impossible d'ouvrir un tube de communication"<<endl;
    		exit(-1);
    	}
     
    	pid=fork();
    	if (pid==0)
    	{ parcours(argv[1],tube); return 1;}
    	else {  
    		close(tube[1]);
    		while (read(tube[0],buffer, sizeof(buffer))>0)
    			{
     					//je gere mon message recu.
    			}
    		close(tube[0]);
     
    	}
    wait(0);
    return 1;
     
    }

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 140
    Par défaut
    Salut,

    Il n'y a pas d'utiliter de passer par un fork, une simple réccursion suffit.

    Dans la fonction parcourt, tu execute un nouveau fils, mais le fils créateur lui ferme le tube. A mon avis çà va créer des problèmes.

  3. #3
    Membre régulier
    Inscrit en
    Janvier 2004
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 10
    Par défaut
    Pour les fork, malheuresement en université le droit de penser par soit meme est mal vu, donc si le monssieur il dis "utilisez des fork" meme si moi aussi ca me parait pas la meilleure solution, ben faut le faire

    Sinon Il faut bien fermer le tube à la fin, mais vu que j'ai fait un fork() ca ajoute à chaque fois un ecrivain de plus, et quand je ferme le tube ca en supprime un. Normallement le lecteur est avertit que quand il n y a plus d'ecrivain, non?

  4. #4
    Membre régulier
    Inscrit en
    Janvier 2004
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 10
    Par défaut
    Bon ben début de reponse, en ajoutant des messages de debug :

    La fonction read renvoie 0 si y'a plus personne qui écris dans le tube, le probleme viens quand y'a plus personne qui ecris ET que le processus qui lis n'a pas tout lu : la fonction read lui renvoie 0 comme signal "il n'y a plus personne qui ecris" pourtant il y a toujours des données non lues dans le tube...


    Comment faire pour passer ca? :s

Discussions similaires

  1. lecture/ecriture des broches RTS/CTS du port RS232
    Par .:: sly51 ::. dans le forum C
    Réponses: 3
    Dernier message: 24/10/2006, 15h28
  2. lecture & ecriture sur le port serie
    Par anouar dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 08/07/2005, 17h15
  3. [JDBC]lecture/ecriture dans une base de donnée
    Par tarik75 dans le forum JDBC
    Réponses: 7
    Dernier message: 30/06/2005, 12h42
  4. [VB.NET] Tableau de bytes Lecture/Ecriture
    Par BenoitM dans le forum Windows Forms
    Réponses: 3
    Dernier message: 05/04/2005, 09h51
  5. [LG]Lecture-ecriture fichier
    Par arno15 dans le forum Langage
    Réponses: 19
    Dernier message: 03/02/2005, 22h25

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