Problème multithread

froggyinfo Messages postés 16 Date d'inscription vendredi 12 décembre 2003 Statut Membre Dernière intervention 31 juillet 2006 - 25 juil. 2006 à 17:36
froggyinfo Messages postés 16 Date d'inscription vendredi 12 décembre 2003 Statut Membre Dernière intervention 31 juillet 2006 - 27 juil. 2006 à 10:30
Bonsoir,

Voila j'ai un problème avec un programme multi-thread,

J'ai raccourci un peu le code est remplacé les fonctions par des recup1 à 4.

Le but du programme :

Le programme doit en fait consulter une base de donnée pour avoir une liste alerte.

Ensuite un certain nombre de thread vont aller taper dans le résultat de l'alerte.
j'utilise alors la classe mutex pour qu'un seul thread puisse accéder à une alerte.
Une fois les informations récupérés ce thread lance lui 4 thread.

Et c'est la que j'ai l'impression que la gestion n'est pas bonne.

Alors soit tout est ok et pour vous il n'y a pas de problèmes.
Ou soit ya un problème et dans ce cas, je veux bien un petit coup de pouce.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Threading;

using System.Data.SqlClient;
using System.Data;
using System.Reflection;    

class Program
    {
        private static Mutex mut = new Mutex();
        private static int nbThread = 3;
        private static bool terminer = false;
        private const string sqlConnexionStr = "chaine de connexion à la base";
        protected SqlDataReader cible;
        private int i = 0;
        
        static void Main()
        {
            Program p = new Program();
            p.lanceThread();
            Console.ReadLine();
        }

        public void lanceThread()
        {
            
            SqlCommand recupCible = new SqlCommand();
            SqlConnection conn = new SqlConnection(sqlConnexionStr);
            recupCible.Connection = conn;
            conn.Open();
            
            try
            {
                recupCible.CommandType = System.Data.CommandType.StoredProcedure;
                recupCible.CommandText = "recupCible";
                recupCible.CommandTimeout = 3600;
                cible = recupCible.ExecuteReader();
            }
            catch (Exception e) {
                Console.WriteLine(e.Message);
            }
            finally
            {
               // conn.Close();
            }

            for (int i = 0; i < nbThread; i++)
            {
                Thread th = new Thread(new ThreadStart(RecupEnvoiMail));
                
                th.Name = i.ToString();
                
                th.Start();
            }
        }

        public void RecupEnvoiMail()
        {
            VarFoncMail v = new VarFoncMail();
            bool read = false;
            while(!terminer)
            {
                mut.WaitOne();
                Console.WriteLine("entré");
                Console.WriteLine("Thread" + Thread.CurrentThread.Name);
                try
                {
                    read = false;
                    if (!terminer)
                    {
                        if (!cible.Read())
                        {
                            terminer = true;
                        }
                        else
                        {
                            i++;
                            Console.WriteLine("-------->>>>>>" + i.ToString());
                            v = new VarFoncMail(
                                System.Convert.ToInt32(cible["idalerte"]));
                            read = true;
                        }
                    }
                }
                catch (Exception e) {
                    Console.WriteLine(e.Message);
                    terminer = true;
                   }
                finally
                {
                    Console.WriteLine("Sortie");
                    mut.ReleaseMutex();
                }
                if (read)
                {
                    try
                    {
                        Thread t = new Thread(new ThreadStart(v.recup1));
                        t.Name = "thread1_" + Thread.CurrentThread.Name;
                        t.IsBackground = true;
                        Thread t2 = new Thread(new ThreadStart(v.recup2));
                        t2.Name = "thread2_" + Thread.CurrentThread.Name;
                        t2.IsBackground = true;
                        Thread t3 = new Thread(new ThreadStart(v.recup3));
                        t3.Name = "thread3_" + Thread.CurrentThread.Name;
                        t3.IsBackground = true;
                        Thread t4 = new Thread(new ThreadStart(v.recup4));
                        t4.Name = "thread4_" + Thread.CurrentThread.Name;
                        t4.IsBackground = true;
                        t.Start();
                        t2.Start();
                        t3.Start();
                        t4.Start();
                        t.Join();
                        t2.Join();
                        t3.Join();
                        t4.Join();
                        
                        try
                        {
                           // execution de code
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.Message);
                        }
                        //Insertion des informations en base
                        Console.WriteLine("fin thread" + Thread.CurrentThread.Name);
                    }
                    catch (Exception)
                    {
                        Console.WriteLine("erreur : ");
                    }
                }
            }
        }
    }

    class VarFoncMail
    {
        //info pour alerte
        public int idalerte;
        public static Random r = new Random(unchecked((int)(DateTime.Now.Ticks)));
        
        

        public VarFoncMail()
        {
        }
        public VarFoncMail(int pidalerte)
        {
            this.idalerte = pidalerte;
           
        }

        public void recup1()
        {
            int t = r.Next(1, 10) * 1000;
            Thread.Sleep(t);
            Console.WriteLine(Thread.CurrentThread.Name + " " + idalerte + "-----" + t);
        }

        public void recup2()
        {
            int t = r.Next(1, 10) * 1000;
            Thread.Sleep(t);
            Console.WriteLine(Thread.CurrentThread.Name + " " + idalerte + "-----" + t);

        }

        public void recup3()
        {
            int t = r.Next(1, 10) * 1000;
            Thread.Sleep(t);
            Console.WriteLine(Thread.CurrentThread.Name + " " + idalerte + "-----" + t);
        }

        public void recup4()
        {
            int t = r.Next(1, 10) * 1000;
            Thread.Sleep(t);
            Console.WriteLine(Thread.CurrentThread.Name + " " + idalerte + "-----" + t);
        }
        
    }

Merci beacoup

Froggyinfo

6 réponses

crougni Messages postés 18 Date d'inscription mardi 20 septembre 2005 Statut Membre Dernière intervention 3 mars 2009
26 juil. 2006 à 08:37
Salut,

pourquoi exactement tu suppose que ton prog fonctionne pas ? tu as constaté un problème précis ou pas vraiement ?

perso, je vois un truc,
qui pourrait faire que sa croucroute, c'est que tes threads RecupEnvoiMail peuvent modifier ta vairable Read chacun leurs tour sans pour autant avoir lancé les 4 sous-threads. Cad que les Thread 0 [RecupEnvoiMail] , lit la première alerte, positionne Read à Vrai, puis le Thread 1 [RecupEnvoiMail], fait pareil, mais n'arrive pas à lire, car par exemple il n'y a plus d'alerte, et du coup positionne Read à faux, alors que ton thread 0 à pas encore lancé ses sous-thread.

Donc moi je n'utiliserai pas du tout ta variable Read, elle sert à rien, et je lancerai mes sous-thread juste après la lecture.

de plus de remplacerai ton mutex par un bon lock(this)

genre :

...
while(!terminer)
            {
                lock(this)
                {
                    Console.WriteLine("entré");
                    Console.WriteLine("Thread" + Thread.CurrentThread.Name);
                    try
                    {
...

Voila, mais si tu pouvais juste décrire le soucis que tu constate....

A+
0
froggyinfo Messages postés 16 Date d'inscription vendredi 12 décembre 2003 Statut Membre Dernière intervention 31 juillet 2006
26 juil. 2006 à 10:34
En fait ce qu'il se passe c'est que j'ai l'impression que les thread ne s'exécutent pas en parallèle mais l'un après l'autre.

Et je ne comprend pas pourquoi ?

Greg
0
froggyinfo Messages postés 16 Date d'inscription vendredi 12 décembre 2003 Statut Membre Dernière intervention 31 juillet 2006
26 juil. 2006 à 10:37
De plus à propos du read, il est propre à chaque thread et non commun à tous les threads.
Je ne comprend pas pourquoi ca viendrait de ma variable read.

Greg
0
froggyinfo Messages postés 16 Date d'inscription vendredi 12 décembre 2003 Statut Membre Dernière intervention 31 juillet 2006
26 juil. 2006 à 15:58
Personne n'a un site à me conseiller pour les thread ?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
26 juil. 2006 à 23:49
Salut,
J'ai simplifié ton code en supprimant tout ce qui était en rapport avec la base donnée.
Et apparement y'a pas de problème, tout semble s'exécuter correctement "en parallèle".

Comment peux-tu affirmer que ce n'est pas le cas.
Ou alors y'a un prob avec la database (je ne peux pas tester ça pour l'instant...)

<hr size="2" />VC# forever
0
froggyinfo Messages postés 16 Date d'inscription vendredi 12 décembre 2003 Statut Membre Dernière intervention 31 juillet 2006
27 juil. 2006 à 10:30
Ok en fait tout s'éxécute bien en parallèle. Je pense que j'ai trouvé le problème. En fait la ou il y a un problème c'est dans les fonctions récup. Dans ces fonctions récup vous vous doutez bien que je ne fais que de mettre en veille des thread heureusement.

En fait dans ces thread j'appelle une fonction d'un web service. Et ce web service lui récupère le contenu html de page. Et en fait, j'ai l'impression qu'il fait les requêtes en série ce web service.

Est ce que vous connaissez un truc pour lancer deux requète différente en meme temps sur un serveur web.

Greg
0
Rejoignez-nous