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 :

Calcul multithread et données "mélangées"


Sujet :

C#

  1. #1
    Nouveau Candidat au Club
    Femme Profil pro
    Inscrit en
    Octobre 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2013
    Messages : 4
    Points : 1
    Points
    1
    Par défaut Calcul multithread et données "mélangées"
    Bonsoir tout le monde!

    Excusez-moi d’entrée pour ce « pavé », mais après des heures de luttes et recherches acharnées, je me résigne à vous faire part de mon problème… En espérant qu’une âme charitable m’aide !

    Voilà mon problème :

    Imaginons que je dispose d’une classe qu’on appellera « Controleur ». Celle-ci se charge de créer un grand tableau dont chaque ligne serait composée de paramètres (des nombres). Chaque ligne étant bien sûr différente et INDEPENDANTE. Mon objectif est d’envoyer ce tableau à une autre classe, qu’on appellera « Analyse », pour que cette dernière, après avoir effectué une série de calculs, complète mon tableau (grâce à une colonne prévue à cet effet !). Ensuite, évidemment, je récupère mon tableau complété dans ma classe « Controleur ». Tout va bien !

    Soit, imaginons maintenant qu’au lieu de faire un seul appel à ma classe « Analyse », je crée désormais plusieurs threads, en leur spécifiant à chacun les numéros de lignes qu’ils devront traiter. Le but étant bien sûr d’accélérer le traitement de mon tableau (pas folle la guêpe !). Par exemple, pour un tableau de 300 lignes, avec 3 threads, le premier s’occupera des lignes 1 à 100, le second s’occupera des lignes 101 à 200 et le dernier s’occupera des lignes 201 à 300.

    Et là … c’est le drame ! Mes threads font un gros « méli-mélo » des variables, comme si elles étaient toutes « statiques ». Résultat, mon tableau est entièrement rempli aléatoirement en sortie !! Pourtant AUCUNE variable n’est déclarée en « statique » dans mes deux classes. Et pour créer mes threads, je crée bien à chaque fois une nouvelle instance de ma classe « Analyse » qui est censé recevoir sa propre copie du tableau original.

    Je ne comprends pas !! H.E.L.P. !! Est-ce que quelqu’un, sans que je mette le code pour l’instant (encore plus pavé sinon !), aurait une petite intuition ?

    Edit : Où sinon si quelqu'un connait LA bonne méthode pour exécuter, une même classe, dans plusieurs threads, le tout en même temps et en empêchant tout échanges! Merciiiii!

    Un grand MERCI par avance !

    K.ROLE42

  2. #2
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Points : 2 605
    Points
    2 605
    Par défaut
    Bonjour.

    Ca va être plutôt délicat de te répondre sans code.

    L'idéal, ce serait un bout de code minimal qui reproduit le comportement.

  3. #3
    Nouveau Candidat au Club
    Femme Profil pro
    Inscrit en
    Octobre 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2013
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Bonjour,
    Merci pour la réponse, voilà à quoi ressemble le code, il est évidemment simplifié, mais le résultat est le même.
    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
    class Controleur
    {
    	//Constructeur et diverses fonctions
    	public void calculMultiThread()	
        {
    		//Création du tableau à résoudre
    		List<Ligne> tableau = new List<Ligne>();		//Une liste de "Ligne" (une classe de getter et setter banale)
    		//Remplissage du tableau
    		[...]
    		//Création des analyses
    		Analyse analyse1 = new Analyse(tableau, 0, 99);
    		Analyse analyse2 = new Analyse(tableau, 100, 199);
    		Analyse analyse3 = new Analyse(tableau, 200, 299);
    		//Création des threads
    		Thread thread1 = new Thread(analyse1.lancerAnalyse);
    		Thread thread2 = new Thread(analyse2.lancerAnalyse);
    		Thread thread3 = new Thread(analyse3.lancerAnalyse);
    		//Démarrage des threads
    		thread1.Start();
    		thread2.Start();
    		thread3.Start();
    		//Attente des threads
    		thread1.Join();
    		thread2.Join();
    		thread3.Join();
    		//Récupération des tableaus complétés
    		List<Ligne> tableau1 = analyse1.getTableau();
    		List<Ligne> tableau2 = analyse2.getTableau();
    		List<Ligne> tableau3 = analyse3.getTableau();
    	}
    }
    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
    class Analyse
    {
    	public Analyse(List<Ligne> tableau, int valeurDebut, int valeurFin)
    	{
    		//valeurDebut et valeurFin sont les lignes à calculer
    		[...]
    	}
     
    	public void lancerAnalyse()
    	{
    		for (i = valDepart; i <= valFin; i++)	//Pour chaque ligne à analyser
            {
    			//Récupérer mes paramètres du tableau
    			getParametres(i);
    			//Effectuer mes calculs
    			[...]
    			//Saisir le résultat
    			tableau[i].setResultat(monResultat);
    		}
    	}
     
    	public List<Ligne> getTableau()
    	{
    		return tableau;
    	}
    }
    Le truc c'est qu'avec un seul thread, tout va bien, j'ai les bons résultats, mais dès lors que j'en met plusieurs, c'est la catastrophe...
    J'ai aussi constaté notamment qu'à l'arrivée, les variables tableau, tableau1, tableau2 et tableau3, sont strictement identiques alors que tableau ne devrait pas avoir de résultats saisies, tableau1 devrait contenir les résultats des lignes 0 à 99, tableau2 des lignes 100 à 199, et tableau3 de 200 à 299. Or, ils sont tous les 3 identiques et 100% complétés (mais faux!).

  4. #4
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Bonjour, d'après ce que je vois il est normal que les trois tableaux soient identiques à "tableau" puisque c'est justement ce dernier qui a été fourni aux constructeurs de analyse1, analyse2 et analyse3. A priori les trois manipulent et renvoient cette même liste (je rappele qu'une liste est passée par référence et non pas par valeur).

    En revanche d'après ce que je vois analyse n'ajoute pas de lignes dans tableau mais se contente de modifier les entrées dont l'index est compris entre valDepart et valFin. Si ceux-ci correspondent bien aux valeurs fournies aux constructeurs et si chaque élément est indépendant, alors il n'y a pas de raison que ça crée de problème et rien dans le code fourni ne peut l'expliquer : le code est bon.

    Donc le problème est ailleurs. Les "setters" ne provoqueraient-ils pas des effets secondaires ? Quid de "getParametres" ?

  5. #5
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Points : 9 743
    Points
    9 743
    Billets dans le blog
    3
    Par défaut
    A priori c'est parce que le tableau est passé en revue en entier.

    Essaies avec ça :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Analyse analyse1 = new Analyse(tableau.Skip(0).Take(99).ToList(), 0, 99);
    Analyse analyse2 = new Analyse(tableau.Skip(100).Take(199).ToList(), 100, 199);
    Analyse analyse3 = new Analyse(tableau.Skip(200).Take(299).ToList(), 200, 299);
    En gros on crée une Analyse et on ne passe que les lignes qu'on veut analyser.

    [EDIT] grillé par DonQuiche
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    A priori le problème est dans une partie du code que tu n'as pas montrée...

  7. #7
    Nouveau Candidat au Club
    Femme Profil pro
    Inscrit en
    Octobre 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2013
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par DonQuiche Voir le message
    (je rappele qu'une liste est passée par référence et non pas par valeur).
    huu, oops! Du coup cela explique mieux mon constat...

    Citation Envoyé par DonQuiche Voir le message
    Donc le problème est ailleurs. Les "setters" ne provoqueraient-ils pas des effets secondaires ? Quid de "getParametres" ?
    Citation Envoyé par DotNetMatt Voir le message
    En gros on crée une Analyse et on ne passe que les lignes qu'on veut analyser.
    Je vais explorer ces deux pistes cet après-midi, je vous tiens au courant, merci!

    Edit : tomlev, oui, désolée, j'étais persuadée que le problème venait de ce morceau de code, puisqu'il apparaît qu'à partir du moment où je repartie le travail dans plusieurs threads...

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par k.role42 Voir le message
    huu, oops! Du coup cela explique mieux mon constat...
    Oui mais a priori ça n'a pas d'importance ; plusieurs threads peuvent travailler sur la même liste, tant qu'ils ne la modifient pas.

  9. #9
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Oui mais a priori ça n'a pas d'importance ; plusieurs threads peuvent travailler sur la même liste, tant qu'ils ne la modifient pas.
    Ca explique une partie du constat : k.role42 s'étonnait que les trois listes soient identiques.

    Mais nous sommes d'accord sur le fait que ça n'explique pas les autres problèmes, l'approche retenue étant valide : les trois threads peuvent travailler en parallèle sur des éléments indépendants, peu importe qu'ils soient dans la même liste (tant qu'ils ne modifient pas celle-ci).

  10. #10
    Nouveau Candidat au Club
    Femme Profil pro
    Inscrit en
    Octobre 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2013
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Problème résolu!

    En fait en relisant le code je me suis rendue compte qu'il y avait bien UNE "List" dont je me servait notamment comme "tampon" dans mes calculs (dans la classe "Analyse"). Associé au fait que "une liste est passée par référence et non pas par valeur" (Merci DonQuiche!), c'est effectivement de là que venait mon erreur. Je l'ai corrigé en créant des "clones" de cette liste.

    Moi qui pensait que c'était ma manière de créer les threads qui était mauvaise, ma piste était fausse, mais c'est le résultat qui compte, Merci à tous!


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

Discussions similaires

  1. Importation de données caractères avec quote
    Par caro92 dans le forum SAS Base
    Réponses: 3
    Dernier message: 25/11/2015, 09h59
  2. [SQL SVR 2K]Données contenant double quote
    Par Franck2mars dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 11/01/2007, 10h46

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