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 :

[Algorithme] Copie liste de fichiers avec 10 threads


Sujet :

Delphi

  1. #1
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut [Algorithme] Copie liste de fichiers avec 10 threads
    Salut!

    Je développe actuellement un programme de copie. J'utilise 10 threads de copie. (un peu comme LeetchFtp). Je voudrais que l'utilisateur puisse sélectionner autant de fichiers qu'il le veut et que le programme détecte lorsqu'un thread se libère pour poursuivre la copie de cette liste. Mon problème, est que je ne sais pas quelle est la meilleure solution à utiliser dans ce genre de cas. Je pensais créer une classe 'TFichier' pour enregistrer les informations des fichiers sources (nom, taille, attributs, position de la copie, temps restant pour a copie, etc) et un tableau dynamique : ListFichier: Array Of TFichier;

    Qu'en pensez-vous ?
    Auriez-vous des idées d'algorithme plus performant ?
    TCollection est une piste intérressante ?

    Merci d'avance.
    De retour parmis vous après 10 ans!!

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    L'utilisation d'un Array ou d'une Collection n'a que peu d'importance, dans ton cas, je ne crois pas qu'une ThreadList soit non plus utile mais je la recommande tout de même

    Regarde simplement autour de Section Critique, tu pourras éviter les conflits de lecture Ecriture ...

    Tes 10 Threads sont lancés en permanence ? dommage d'utiliser de la ressource à ne rien faire ...

    Tu as une demande de télécharger 27 fichiers, tu lances tes threads, et tu comptes le nombre de Thread Actif (un entier encapsulé dans un objet singleton avec une section critique sur l'accesseur, ce compteur est augmenté dans le constructeur d'un Thread, et diminue à la fin du Execute ou dans le Destroy si tu mets FreeOnTerminate à True), tu as donc 10 fichiers en Cours, et 17 en attente, pour ce qui est des progessions, ça tu vois avec les objets FTP, je l'ai fait avec un TNMFTP créé dans le Thread avec un AS400 derrière, comme tu as des fichiers en attente, tu lance un Timer ou un Thread de Queue

    Ensuite, tu as un Timer, qui scrute la liste (le Thread de Queue en faite), si il y a des fichiers à télécharger, tu regarde le compteur, si il est à 10, tu ne fais rien, si il y en a moins, tu lance autant que possible pour le nombre de fichiers restant ...

    Donc, en gros F1 sur TThreadList, TCriticalSection, les Pointeurs, ...
    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
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    Réponse très intérressante. Merci ShaiLeTroll.

    Cela dit, j'ai déjà développé ma classe de thread. Cette classe regroupe les propriétés et méthodes nécessaires au transfert de données. Voici sa déclaration (simplifiée) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Const MaxThreads = 10;
     
    Type
      THttpThread = Class(TThread)
      ...
      End;
     
    Var HttpThreads: Array [0..MaxThreads - 1] Of THttpThread;
    Tout ceci fonctionne parfaitement bien, je n'ai pas envie de tout recoder... C'est juste la partie "gestion de la liste des fichiers et distribution des threads que je dois réaliser.

    Ce que je comptais faire était une déclaration similaire : Une classe d'objet "TFichier" avec son tableau dynamique typé, et un timer qui se chargerait de parcourir cette liste à la recherche des fichiers à transmettre et de rechercher les threads libres pour les allouer à ces fichiers.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Type
      TFichier = Class
        ThreadIndex: Integer;
        ...
      End;
     
    Var ListFichier: Array Of TFichier;
    L'objet TFichier sera libéré dès que son transfert sera terminé et le tableau dynamique possèdera alors un "élément" libre. Si l'utilisateur ajoute de nouveaux fichiers à copier (pendant la copie), il faudra que je parcours le tableau dynamique à la recherche d'un index libre pour stocker le fichier... ou bien si il n'ya plus de place libre, augmenter la taille du tableau avec SetLength... c'est lourd, non ?
    De retour parmis vous après 10 ans!!

  4. #4
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 858
    Points : 11 302
    Points
    11 302
    Billets dans le blog
    6
    Par défaut
    pour ma part, je vois bien un TQueue que tu charges avec des Push(fichier) et que chaque thread se terminant va inspecter d'un Pop pour se relancer...
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  5. #5
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    Citation Envoyé par tourlourou
    pour ma part, je vois bien un TQueue que tu charges avec des Push(fichier) et que chaque thread se terminant va inspecter d'un Pop pour se relancer...
    Voilà! C'est ça qu'il me faut.
    De retour parmis vous après 10 ans!!

  6. #6
    Membre averti

    Homme Profil pro
    Inscrit en
    Octobre 2003
    Messages
    908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 908
    Points : 447
    Points
    447
    Par défaut
    Pourquoi ne pas utiliser un sémaphore pour la gestion du nombre de thread ?

    Chaque fois qu'un thread termine sa copie il libère une place du sémaphore et un autre thread peut commencer.

  7. #7
    Membre averti

    Homme Profil pro
    Inscrit en
    Octobre 2003
    Messages
    908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 908
    Points : 447
    Points
    447
    Par défaut
    C'est meme beaucoup mieux que de faire avec un entier !

    Le sémaphore est "spécialisé" pour la gestion de ressource.

  8. #8
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    Chaque fois qu'un thread termine sa copie il libère une place du sémaphore et un autre thread peut commencer.
    Oui, ça semble être une bonne solution également.
    Je vais lire le tutoriel sur les sémaphores et voir si l'implémentation dans mon cas est facile.
    De retour parmis vous après 10 ans!!

  9. #9
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Cela m'intéresse, un Semaphore en Delphi, ... si j'ai le temps, j'y jetterais aussi un coup d'oeil ...
    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

  10. #10
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2003
    Messages : 582
    Points : 915
    Points
    915
    Par défaut
    Je dis +1 à ShaiLeTroll

    TThreadList équivaut pratiquement à TQueue...
    seulement qu'on est thread-safe.

    Si tu utilise une TQueue avec des thread, va falloire que
    tu ajoute des sections critique etc...

    Vaux mieux dans ce cas prendre directement un TThreadList.
    Bon en gros:
    TQueue
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    //Lock
    Push(AItem: Pointer);
    //unlock
     
    //Lock
    Pop: Pointer;
    //Unlock
    TThreadList
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Add(Item: Pointer); //Push
    //un equivalant du pop;
    with TThreadList.LockList do
    begin
      if count>0 then 
      begin
        result:=Items[0];
        Delete(0);
      end
      else
          result:=nil;
      UnlockList;
    end;
    Ensuite, dans ton execute du Thread qui copie,
    quelque chose du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      FileObject=Pop;
      while FileObject<>nil do
      begin
          //Copy FileObject....
          FileObject=Pop; //Get Next File to copy
      end;
    Comme ca, un thread de copie ce ferme seulement lorsqu'il n'y a plus de fichier disponible dans la liste...

    Ici, les thread cherche du travail à effectuer dans une liste....
    Les Semaphore selon moi c'est un peu l'inverse, c'est la liste qui cherche un
    thread de copie libre...

    C'est bien à toi de voir où ton code est le mieux placer pour travailler dans un sens ou dans l'autre....
    Comment dupliquer un disque...ça vous intéresse?
    Tutoriel et code source delphi ici

  11. #11
    Membre habitué
    Inscrit en
    Juin 2005
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 207
    Points : 161
    Points
    161
    Par défaut
    Je vais peut-être m'aventurer hors du sujet, mais si ma conception du problème est juste, tu dois forcément avoir un thread principal qui créer les threads secondaires (ceux qui effectuent la copie)

    Bon, je met tout ça entre parenthèses vu que je n'ai jamais abordé l'aspect des threads en Delphi, mais je les utilise beaucoup en C... Donc je continue...

    Le thread principal, dans ce cas, est chargé de lancer les threads 'enfants'.

    Donc premier point, le thread principal gérant la création/destruction des threads destinés à la copie, tu est en mesure de limiter leurs nombres...

    Ensuite, autant utiliser le thread parent pour ordonnancer le système...

    Ainsi:

    1) Création du thread parent, attente de commande 'copie'
    2) La liste des fichiers à copier est créée dans le thread parent
    3) Pour chaque élément de la liste/queue, le thread parent regarde s'il peut instancier un thread enfant.
    - Si oui, créer un thread enfant et le charge de copier le fichier désiré
    - Si non, attend qu'un thread enfant se termine

    Le gros intérêt, c'est que tu ne te compliques pas à gérer les accès concurrents vu que c'est le thread parent qui gère tout seul les fichiers à copier (il joue le rôle d'ordonnanceur)

  12. #12
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    Citation Envoyé par Gaadek
    Le gros intérêt, c'est que tu ne te compliques pas à gérer les accès concurrents vu que c'est le thread parent qui gère tout seul les fichiers à copier (il joue le rôle d'ordonnanceur)
    C'est exactement ça. Le thread principale est celui du programme.
    De retour parmis vous après 10 ans!!

  13. #13
    Membre averti

    Homme Profil pro
    Inscrit en
    Octobre 2003
    Messages
    908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 908
    Points : 447
    Points
    447
    Par défaut
    Ma question va paraitre un peu bete , mais quel est l'avantage d'avoir une gestion avec un ordonnateur ????


    Pour faire toutes mes applications en multi-thread, la meilleure solution c'est de privilégié l'aspect concurrentiel avec des sémaphores,c'est plus rapide est plus efficace( beaucoup moins de code aussi). c'est un objet de synchro de base, arretez de réinventer la roue.

    Aprés une petite idée (on ne sait jamais) au lieu de dire par défaut que ton programme fait 10 threads pourquoi ne pas lancer un petit programme qui fait des tests et qui déterminera le nombre de thread en fonction du type d'ordinateur ?

    Fait aussi attention a la priorité des threads pour rendre ton appli efficace ...

  14. #14
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    Citation Envoyé par Eric Boisvert
    Ici, les thread cherche du travail à effectuer dans une liste....
    Les Semaphore selon moi c'est un peu l'inverse, c'est la liste qui cherche un thread de copie libre...
    C'est bien à toi de voir où ton code est le mieux placer pour travailler dans un sens ou dans l'autre....
    Justement, je me pose la question. Admettons que j'ai le choix...
    Quelle est la méthode la plus performante et/ou la plus simple selon vous ?

    Citation Envoyé par rvzip64
    Aprés une petite idée (on ne sait jamais) au lieu de dire par défaut que ton programme fait 10 threads pourquoi ne pas lancer un petit programme qui fait des tests et qui déterminera le nombre de thread en fonction du type d'ordinateur ?

    Fait aussi attention a la priorité des threads pour rendre ton appli efficace ...
    Le nombre 10 c'est pour faire simple, mais par la suite, je peux définir un nombre maximal en fonction des ressources disponibles.
    type du processeur
    vumètre cpu

    Quand à la priorité, que me conseillez-vous ?
    De retour parmis vous après 10 ans!!

  15. #15
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    Merci pour vos réponses. Je progresse grâce à vous !

    En fait, je pense que ce ne sont pas aux threads d'aller vérifier si il ya des fichiers à transférer. Selon moi, c'est au thread principal à distribuer les fichiers aux threads libres. Si vous pensez le contraire, merci d'argumenter un peu.

    Eric Boisvert: Comme je l'ai dis à ShaiLeTroll dans mon 2ème message, je ne compte pas utiliser une TThreadList car j'ai déjà mis au point le fonctionnement des threads qui est assez "complexe" en fait (timeout, reprise du transfert, affichage des messages non répétitifs, etc...), je n'ai pas envie de reprendre cette partie du code. Le tableau de Threads fonctionne parfaitement; Un thread est libre lorsqu'il est suspendu, c'est tout ce que j'ai besoin de savoir. La gestion de la liste des fichiers et la distribution me semble devoir être à part, et fonctionner dans le thread principal du programme.

    Je suis en train d'étudier les sémaphores pour voir si ils peuvent vraiment apporter un plus par rapport à une programmation basique, par exemple avec un timer et une recherche des threads libres, genre :
    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
    Procedure TForm1.AjoutButtonClick(Sender: TObject);
    Begin
      If (OpenDialog1.Execute) Then
        ListFichier.Add(OpenDialog1.Files);
      Timer1.Enabled := (ListFichier.Count > 0);
    End;
     
     
    Procedure TForm1.Timer1Timer(sender: TObject);
    Begin
      Timer1.Enabled := False;
     
      // Distribution des fichiers aux threads libres
      For i := Low(HttpThreads) To High(HttpThreads) Do
        With HttpThreads[i] Do
          If (Suspended) Then Begin
     
            // Thread libre 
            Resume;
            ...
          End;
     
      Timer1.Enabled := (ListFichier.Count > 0);
    End;
    Par contre, il ne faut pas que cette fonction bloque le programme, l'utilisateur doit pouvoir ajouter des fichiers dans la liste ou effectuer d'autres opérations...
    De retour parmis vous après 10 ans!!

  16. #16
    Membre habitué
    Inscrit en
    Juin 2005
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 207
    Points : 161
    Points
    161
    Par défaut
    Citation Envoyé par rvzip64
    Ma question va paraitre un peu bete , mais quel est l'avantage d'avoir une gestion avec un ordonnateur ????


    Pour faire toutes mes applications en multi-thread, la meilleure solution c'est de privilégié l'aspect concurrentiel avec des sémaphores,c'est plus rapide est plus efficace( beaucoup moins de code aussi). c'est un objet de synchro de base, arretez de réinventer la roue.

    Aprés une petite idée (on ne sait jamais) au lieu de dire par défaut que ton programme fait 10 threads pourquoi ne pas lancer un petit programme qui fait des tests et qui déterminera le nombre de thread en fonction du type d'ordinateur ?

    Fait aussi attention a la priorité des threads pour rendre ton appli efficace ...
    Je n'ai pas signaler qu'il fallait utiliser un ordonnanceur, mais que le thread principal jouait ce rôle.... La nuance fait toute la différence!

    L'odronnanceur, à part pour les système temps réels, je n'en vois pas l'intérêt ni les applications (mais je suis loin de tout connaître également )

    De plus, pourquoi absolument vouloir jouer avec les sémaphores si on peut s'en passer? C'est autant de problèmes/risques de blocages en moins!

    Enfin, pour faire avancer le schmilblick, il faudrait regarder au niveau de la création des threads s'il ne serait pas plus intéressant de procéder ainsi:

    - Le thread parent créer un thread enfant pour effectuer une copie
    - Lorsque le thread enfant a terminé, il se tue
    - Le thread parent se charge de lancer au maximum x thread enfants.

    Ainsi, le thread principal se charge de 3 choses:
    - Contrôler la liste de fichiers à copier
    - Contrôler le nombres d'enfants existants, et ce pour savoir s'il peut en créer de nouveaux
    - Créer un thread enfant et lui donner un job à faire (la copie)

    Le point bloquant dans cette histoire, c'est que si la création d'un thread est trop longue, alors dès le départ, le système est bridé (surtout dans le cas de copie multiple de petits fichiers, sur les gros fichier, cela restera acceptable)

  17. #17
    Membre averti

    Homme Profil pro
    Inscrit en
    Octobre 2003
    Messages
    908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 908
    Points : 447
    Points
    447
    Par défaut
    Désolé mais je tiens tete

    De plus, pourquoi absolument vouloir jouer avec les sémaphores si on peut s'en passer? C'est autant de problèmes/risques de blocages en moins!
    Je suis pas d acord avec toi , le fait d'utiliser les sémaphores évitent de faire des blocages et simplifie le code.

    Essaue de faire les deux codes un sans les sémaphores et un avec , on vera lequel est le plus compliqué et lequel tu débugueras le plus vite.

    Comme je l ai dit la dernière fois, essayez d'arreter de réinventer la roue ....

  18. #18
    Membre averti

    Homme Profil pro
    Inscrit en
    Octobre 2003
    Messages
    908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 908
    Points : 447
    Points
    447
    Par défaut
    Tipiquement pour ce type d'application, il faudrait un mutex qui permette de synchroniser sur la variable qui contient les fichiers a copié, un sémpahore qui gère les ressources (nombre de thread).

  19. #19
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    Citation Envoyé par Gaadek
    - Le thread parent créer un thread enfant pour effectuer une copie
    - Lorsque le thread enfant a terminé, il se tue
    - Le thread parent se charge de lancer au maximum x thread enfants.

    Ainsi, le thread principal se charge de 3 choses:
    - Contrôler la liste de fichiers à copier
    - Contrôler le nombres d'enfants existants, et ce pour savoir s'il peut en créer de nouveaux
    - Créer un thread enfant et lui donner un job à faire (la copie)
    Cette méthode rejoint ce que j'ai expliqué dans mon 2ème message :
    Citation Envoyé par sub0
    L'objet TFichier sera libéré dès que son transfert sera terminé et le tableau dynamique possèdera alors un "élément" libre. Si l'utilisateur ajoute de nouveaux fichiers à copier (pendant la copie), il faudra que je parcours le tableau dynamique à la recherche d'un index libre pour stocker le fichier... ou bien si il n'ya plus de place libre, augmenter la taille du tableau avec SetLength... c'est lourd, non ?
    Je pense que je vais utiliser un sémaphore, ça m'a l'air tout à fait adapté à ce genre de programmes. Seulement, est-ce portable ? Vais-je pouvoir utiliser ce code avec Kylix par exemple ? Et est-ce compatible avec Win95 & 98 ?
    De retour parmis vous après 10 ans!!

  20. #20
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2003
    Messages : 582
    Points : 915
    Points
    915
    Par défaut
    Citation Envoyé par Sub0
    Eric Boisvert: Comme je l'ai dis à ShaiLeTroll dans mon 2ème message, je ne compte pas utiliser une TThreadList car j'ai déjà mis au point le fonctionnement des threads qui est assez "complexe" ...
    Désolé d'insister Sub0, mais vais quand même te montrer ou je vois l'utilité
    d'un TThreadList.

    Dans la solution que tu propose, Ce qui me chagrine un peu, c'est le besoin
    d'utiliser un timer, et l'obligation de chercher un thread libre..etc..

    tandis qu'avec l'utilisation d'une TThreadList pour maintenir
    une liste de fichier, avec l'ajout d'un Event....
    ca peut prendre l'allure suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
                                    |Thread
                                    |Copie
                                    |File #1
                                   /
      Thread        TThreadList   / |Thread
    Principale   =>    de       =>--|Copie
    Application      fichier      \ |File #2
                     (Fifo)        \
                  (thread-safe)     |Thread
                                    |Copie
                                    |File #X
    dans la ThreadList de fichier on utilisera un Event pour réveiller nos thread de
    copie.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    NewData:THandle;  //Event qui reveillera un de nos thread de copie
    NewData:=CreateEvent(null,FALSE,FALSE,'EventListeFichierNewData');
     
    //lorsqu'il y a un push, on fait un
    SetEvent(NewData);
    //ca va reveiller un des Thread de copie
    ensuite, la boucle pricipale du thead de copie peut ressembler à ca:
    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
     
    //boucle pricipale du thead de copie
    Procedure TMyThreadCopie.Execute;
    Begin
      FreeOnTerminate:=TRUE;
      Repeat
        FileObject=MyThreadListFile.Pop;
        while (FileObject<>nil) and (not Terminated) do
        begin
          //Copy a FileObject....
          //(ton code existant quoi?)
          FileObject=MyThreadListFile.Pop; //Get Next File to copy
        end;
        //ici on attend des nouvelles données cette boucle prend 0% cpu!
        while (WaitForSingleObject(MyThreadListFile.NewData,1000)=WAIT_TIMEOUT do
        begin
            if Terminated then break;
        end;
      Until (Terminated);
    End;
    Comme tu vois, les thread de copie vont pratiquement dormire jusqu'à
    l'arrivé d'une nouvelle donnée dans la liste de fichier.

    Du côté de l'application, on fait des push de fichier n'importe quand...
    Bon c'est plutôt classique comme approche?

    Et finalement, c'est peut-être complètement à côté de ce que tu désire faire...
    Comment dupliquer un disque...ça vous intéresse?
    Tutoriel et code source delphi ici

Discussions similaires

  1. Copie d'un fichier avec des caractères spéciaux
    Par totofe dans le forum Scripts/Batch
    Réponses: 5
    Dernier message: 15/09/2010, 12h28
  2. Liste de fichiers avec liens et classement
    Par illidan05 dans le forum Excel
    Réponses: 1
    Dernier message: 21/05/2008, 14h48
  3. recuperer liste de fichier avec http
    Par etoileDesNeiges dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 10/04/2007, 12h02
  4. Réponses: 16
    Dernier message: 07/04/2005, 11h36

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