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

 Delphi Discussion :

Problème avec du multithread [Débutant(e)]


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 108
    Par défaut Problème avec du multithread
    Bonjour à tous,

    Je vais avoir besoin de vos lumières au sujet de la création d'une application multithread.

    Alors voilà : j'ai une application qui, via des proxies contenu dans le Memo1, va se connecter à mon site et tenter de récupérer une info. Si l'info récupérée est correcte, alors l'application ajoute le proxy utilisé au Memo2.
    L'application fonctionne très bien dans son état actuel, mais le processus est extrêmement long car l'application gère un proxy par un proxy.
    Donc je me suis dit que ce serait une bonne idée de créer une application multithread qui va gérer par exemple 20 proxies par 20 proxies.

    Le problème que j'ai vient vraiment de la gestion de ces threads et non du processus de travail des proxies.
    J'ai déjà créer des applications avec un thread (basique), mais jamais de multithread...

    Voici mon code actuel (allégé) :
    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
    procedure TCheck.Execute;
    var
      s, resp, ip, port : string;
      i, j : integer;
      HTTP: TIdHTTP;
    begin
      checked := 0;
      HTTP := TIdHTTP.Create(nil);
      for j := 0 to Form1.Memo1.Lines.Count-1 do
      begin
        if Form1.CheckBox1.Checked = True then
        begin
          HTTP.Free;
          Exit;
        end;
        s := Form1.Memo1.Lines[j];
        i := Pos(':', s);
        ip := Copy(s, 1, i-1);
        port := Copy(s, i+1, Length(s));
        try
          HTTP.ProxyParams.ProxyServer := ip;
          HTTP.ProxyParams.ProxyPort := StrToInt(port);
          HTTP.ReadTimeout := 30000;
          resp := HTTP.Get('http://www.monsite.com');
          if resp <> 'Valide' then Form1.Memo2.Lines.Add(ip+':'+port);
        except
        end;
        checked := checked+1;
        if (checked = Form1.Memo1.Lines.Count) then
        begin
          HTTP.Free;
          Exit;
        end;
      end;
      HTTP.Free;
    end;
    Dans l’idéal je souhaiterais gérer le nombre de Threads maximum dans un TSpinEdit (ça me semble fastoche).
    Aussi j'ai peur que les threads se mélangent entre eux et qu'un thread ne retente l'opération avec un proxy déjà testé ou en cours de teste...
    Enfin, j'imagine que tout ça est bien géré par Delphi ; on est en 2011 quand même !

    Merci par avance aux réponses et aux pistes !

    Beny

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 093
    Par défaut
    Fait un Try Finally, cela évitera de faire le Free+Exit, le finally est exécuté quoi qu'il arrive, c'est conçu pour cela !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
      ...
      HTTP := TIdHTTP.Create(nil);
      try
        ...
      finally
        HTTP.Free;
      end;
    end;
    Pour ta gestion de thread !
    Tu devrais éviter d'utiliser le Memo que ce soit en Lecture ou Ecriture (en Multi-Thread, le TMemo risque d'exploser, typiquement lors du Add, il va écrire le début d'un thread, soudain ça passe au texte d'un autre, puis celui du précédent)

    Première solution :

    Lors du Create du TCheck, tu passe en paramètre IP et Port
    Le Thread ne tourne que sur ce couple, pas de boucle !
    IP et Port seront des propriétés en lecture seule de ton TCheck (ils seront affectés durant le constructeur via les paramètres)
    Un boolean (une propriété) est mise à True en fonction du succès ou pas
    Tu affecte un OnTerminate où tu liras ce booleen, avec IP et Port, tu sauras qui ne fonctionne pas, et comme OnTerminate est synchronisé tu pourras ajouter dans Memo2
    Mets aussi FreeOnTerminate pour TCheck

    Ajoute un TCheckPool (un thread aussi), à sa création, tu fourni le nombre de thread maximal et la liste des IP:Port

    Tu lance le nombre de TCheck avec chacun un couple IP:Port de Memo1
    Puis une fois le nombre obtenu, tu lance un WaitForMultipleObjects INFINITE
    Tu passe un Array[] of THandle, rempli via les handles de chaque thread !
    Lorsqu'un thread aura terminé, WaitForMultipleObjects devrait envoyer une valeur comme (WAIT_OBJECT_0 + nombre de TCheck - 1), en réalité, la valeur t'importe peu, tu prends IP:Port dans la liste à traiter et tu relance un nouveau TCheck, tu continues de lancer WaitForMultipleObjects dans une boucle tant que l'index dans la liste n'est pas arrivé à count !


    Seconde solution :

    Tu connais le nombre de couple IP:Port et le nombre de thread
    A chaque TCheck, tu passe un array of string contenant les IP:Port,
    TCheck fera une boucle sur array of string
    TCheck aura une propriété array of boolean, chaque case correspondra à un IP:Port
    OnTerminate te permettra de lire les deux array et de remplir memo2
    le nombre couple IP:Port que tu passe c'est Memo1.Lines.count div ThreadCount
    Le dernier thread aura le modulo
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre actif
    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 108
    Par défaut
    Merci ShaiLeTroll pour ces idées !
    Je vais examiner tout ça de plus prêt.

    Beny

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Par défaut
    L'exemple que j'avais donné ne fonctionne pas pour toi ? Bon c'est vrai, les threads j'ai encore un peu de mal et j'avais codé ça a l'arrache mais mes tests semblaient ok !?

  5. #5
    Membre actif
    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 108
    Par défaut
    Citation Envoyé par GoustiFruit Voir le message
    L'exemple que j'avais donné ne fonctionne pas pour toi ? Bon c'est vrai, les threads j'ai encore un peu de mal et j'avais codé ça a l'arrache mais mes tests semblaient ok !?
    Si justement !
    J'ai repris ton exemple comme base, et à côté j'ai recommencé un nouveau projet Delphi.
    Repartir de zéro est plus agréable.

    La gestion du multithread est encore assez difficile pour moi
    Merci pour ton exemple, il m'a beaucoup aidé !

    Avec ton exemple, qu'en est-il de l’avertissement donné par ShaiLeTroll ?
    Je cite :
    Tu devrais éviter d'utiliser le Memo que ce soit en Lecture ou Ecriture (en Multi-Thread, le TMemo risque d'exploser, typiquement lors du Add, il va écrire le début d'un thread, soudain ça passe au texte d'un autre, puis celui du précédent)
    Beny

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Par défaut
    C'est vrai que ma méthode est un peu bof bof: je crée et lance un certain nombre de threads, et quand ils ont terminé leur boulot, j'en crée et lance de nouveaux s'il reste des proxies à tester... Un pool de threads serait sûrement plus adapté, mais je débute avec ces concepts... enfin si tu améliores le truc, n'hésite pas à partager ton code, ça m'intéresse ;-)

Discussions similaires

  1. Encore un problème avec le multithread
    Par Mario Rousson dans le forum VB.NET
    Réponses: 4
    Dernier message: 17/11/2014, 23h12
  2. C# Problème avec le Multithreading
    Par CleeM dans le forum C#
    Réponses: 1
    Dernier message: 23/01/2013, 15h02
  3. Réponses: 8
    Dernier message: 04/03/2009, 14h39
  4. Multithreading : problème avec Abort()
    Par mrrenard dans le forum C#
    Réponses: 7
    Dernier message: 29/10/2007, 17h02
  5. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10

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