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

Entrée/Sortie Java Discussion :

Lecture d'un même fichier en multithreading


Sujet :

Entrée/Sortie Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2007
    Messages : 10
    Par défaut Lecture d'un même fichier en multithreading
    Bonjour,

    J'ai un programme qui doit rechercher des chaines de caractères dans un unique fichier. Ce programme lance un thread pour chaque chaine différente à rechercher dans mon unique fichier.
    Jusqu'à présent, chaque thread ouvre le fichier et parcourt les lignes à la recherche de sa chaîne de caractère. Du coup, forcément, ce n'est pas très efficace. Il y a certainement plus rapide.

    Donc, maintenant, je veux optimiser ces recherches. J'ai donc créé un singleton qui lit le fichier et le mets dans un buffer. Jusque là tout va bien. Maintenant, j'ai besoin que chaque thread puisse parcourir ce buffer de manière indépendante pour faire sa propre recherche. Et là, c'est le drame !
    Si j'utilise les méthodes habituelles de parcours d'un buffer, le multithreading fait que tout le monde s'emmêle les pinceaux. Pas mieux avec les regex.

    Existe t-il une classe permettant de parcourir un buffer sans que le pointeur de positionnement du buffer soit lié à la classe du buffer ?
    Je voudrais aussi éviter de copier mon buffer dans chaque thread.

    Merci pour votre aide.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Citation Envoyé par Thierry5 Voir le message
    le multithreading fait que tout le monde s'emmêle les pinceaux
    Pour ça il existe le mot clé synchronized.
    Placé au bon endroit, il n'y aura plus "d'emmêlage" de pinceaux.
    Mais ça peut générer des latences car les threads ne peuvent pas tous passer en même temps dans le code synchronisé. Donc à utiliser de manière très localisée et avec parcimonie.

  3. #3
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster ;) (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag :resolu:

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  4. #4
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Pourquoi tu ne testre par toutes les chaines en même temps dans un seul thread? Ce qui ralentit l'application dans ce cas ci, ce n'est pas temps le CPU mais les IO. Or multithreader ne sert qu'à optimiser l'utilisation CPU, ce qui n'est déjà pas ton point de ralentissement ici. Tu ne va rien y gagner.

    Par plutot sur cette logique:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    tant que une ligne est lue du fichier
      pour chaque chaine à chercher
        si ligne contient chaine à rechercher alors action
    Maintenant ce que tu peux éventuellement faire c'est avoir un Thread 1 qui lit ligne par ligne le fichier et met les lignes dans une BlockingDeque et avoir un thread2 qui, pour chaque ligne lue, la scanne à la rechreche de pattern.

    Au moins là tu aura le CPU qui tourne en parallèle avec les disques.

  5. #5
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2007
    Messages : 10
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Pourquoi tu ne testre par toutes les chaines en même temps dans un seul thread?
    Malheureusement, je ne maîtrise pas toute la chaîne : je n'ai pas la main sur le process principal qui va générer autant de thread que de chaînes à rechercher...

  6. #6
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    charbuffer n'est pas threadsafe et c'est tout.
    Tu ne veux pas de synchronized -> un charbuffer par thread. Et tu va multiplier d'autant tes IOs, ce qui va écrouler l'application.

    Solution -> oublier l'idée des thread et tout regrouper.

    Je rajoute qu'il ya a quelques erreurs de perfs dans ton code à corriger avant même d'envisager la parallélisation pour "optimiser". Il vaut mieux commencer par faire un code performant avant d'imaginer que le multithread est une solution magiques aux performances.

    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
        private boolean grep(CharBuffer cb, String direct) {
        	boolean bTrouvee = CodeRetour.SEARCH_NOTFOUND;
    	StringBuffer directive = new StringBuffer(direct); // pourquoi en faire un StringBuffer???
    	ligneRecherchee = new String(); //String vide inutile
    	Matcher lm = linePattern.matcher(cb);	// Si le but est de découper en lignes, un BufferedReader sera plus performant et simple à utiliser!
    	int lines = 0;
    	while (lm.find() && !bTrouvee) {
    		lines++;
    		ligneRecherchee=lm.group(); // The current line
     
    		// pourquoi mélanger une recherche par regexp (linePattern et un indexOf??)
                    // un toString() dans une boucle, totalement inutile, fait le toString une seule fois avant la boucle.
    		if (ligneRecherchee.indexOf(directive.toString())>0) {
    	    		System.out.println("grep	Thread ID : "+Thread.currentThread().getId()+"	Directive trouvée : " + directive);
    	    		ligneTrouvee=ligneRecherchee;
    		    	bTrouvee = CodeRetour.SEARCH_FOUND;
    		}
    		if (lm.end() == cb.limit()) //test inutile, find renverra false dans le while!
    		    	break;
    	}
    	return bTrouvee;
        }

  7. #7
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2007
    Messages : 10
    Par défaut
    Merci pour vos réponses rapides !

    Concernant le multithreading, j'ai lu et relu des doc, j'ai fait des tas de tests, mais je n'ai pas trouvé la solution.
    Et concernant le mot clé "synchronized", je ne veux pas l'utiliser dans ce contexte car cela signifierait que je perds tout le temps que je cherche à gagner : au contraire, je souhaite que chaque thread puisse effectuer sa recherche en parallèle des autres et non de manière séquentielle mais sur un même buffer partagé.
    Dans les classes que j'ai trouvé, toutes les méthodes de parcours d'un buffer incluent le buffer ET le positionnement dans le parcours du buffer. Là est mon problème. Car chaque thread doit pouvoir parcourir le buffer en même temps que les autres, mais son positionnement dans le buffer doit lui être propre.

    Bon, je vais essayer d'illustrer.

    Ci-dessous ma fonction de recherche où tout s'embrouille :
    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
     
        private String ligneTrouvee = new String();
        private Pattern linePattern = Pattern.compile(".*\r?\n");
        private String ligneRecherchee;
     
        /**
         * Recherche la directive dans le buffer passé en paramètre.
         * 
         * @param cb CharBuffer contenant le fichier de log à parcourir pour trouver la directive
         * @param direct Directive à retrouver dans le buffer
         * @return boolean Retourne CodeRetour.SEARCH_FOUND si la directive a été trouvée, CodeRetour.SEARCH_NOTFOUND dans le cas contraire 
         */
        private boolean grep(CharBuffer cb, String direct) {
        	boolean bTrouvee = CodeRetour.SEARCH_NOTFOUND;
    	StringBuffer directive = new StringBuffer(direct);
    	ligneRecherchee = new String();
    	Matcher lm = linePattern.matcher(cb);	// Line matcher
    	int lines = 0;
    	while (lm.find() && !bTrouvee) {
    		lines++;
    		ligneRecherchee=lm.group(); // The current line
     
    		if (ligneRecherchee.indexOf(directive.toString())>0) {
    	    		System.out.println("grep	Thread ID : "+Thread.currentThread().getId()+"	Directive trouvée : " + directive);
    	    		ligneTrouvee=ligneRecherchee;
    		    	bTrouvee = CodeRetour.SEARCH_FOUND;
    		}
    		if (lm.end() == cb.limit())
    		    	break;
    	}
    	return bTrouvee;
        }
    Mon CharBuffer est commun à tous les threads.
    J'utilise les RegEx pour identifier les lignes dans mon Buffer, puis je recherche ma "directive" (différente pour chaque Thread) dans la ligne.
    Et là, de manière générale, mes résultats sont incohérents : avec plusieurs threads qui font des recherches différentes, je vais me retrouver avec la même ligne en résultat ou avec une ligne qui n'est pas la bonne...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. lecture même fichier mais un clear avant
    Par med.doc dans le forum Octave
    Réponses: 2
    Dernier message: 24/05/2014, 12h01
  2. Réponses: 5
    Dernier message: 31/10/2013, 09h42
  3. [POI]: ecrire dans le même fichier que celui en lecture
    Par mouss4rs dans le forum API standards et tierces
    Réponses: 1
    Dernier message: 21/02/2012, 18h00
  4. Optimisation de la lecture de tres gros fichiers
    Par Lydie dans le forum C++Builder
    Réponses: 4
    Dernier message: 12/07/2004, 14h09
  5. utiliser le même fichier dans plusieurs projets vc++6
    Par yannick_sch dans le forum MFC
    Réponses: 5
    Dernier message: 12/02/2004, 17h39

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