begin process at 2013 05 24 23:16:08
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Système

 > EXEMPLES DE THREADS

EXEMPLES DE THREADS


 Description

Cliquez pour voir la capture en taille normale
L'objectif final est de suivre la progression en temps réel de traitements longs. Cet objectif n'est pas pleinement atteint dans l'état actuel du code.

Mais j'ai du me familiariser avec les concepts subtils des Threads dont l'exécution n'est pas linéaire. Afin de faire profiter les débutants des développements progressifs de mes tests, plusieurs exemples sont donnés ici par le biais de 3 projets :

Projet 1 : 2 exemples minimalistes comme on en trouve déjà sur la toile

Projet 2 : 2 threads indépendants : voyant clignotant et progressbar d'une boucle fictive

Projet 3 : un mini projet réel de parcours et de traitement de fichier. Les threads sont dépendants et contrôlés.
le projet comprend un générateur de fichiers tests. Dès que le test est terminé, le fichier change d'extension afin de générer automatiquement un autre fichier de test.

Source

  • Trois projets sont fournis avec chacun une seule unité.
  • Les sources sont détaillés mais j'y ai adjoint un fichier de description synthétique et détaillé également pour les débutants: "Utilisation des Threads.pdf".
  • j'y explique les problèmes qui se sont posés à moi et les solutions pour les résoudre ou les choix temporaires effectués.
Trois projets sont fournis avec chacun une seule unité. 
Les sources sont détaillés mais j'y ai adjoint un fichier de description synthétique et détaillé également pour les débutants: "Utilisation des Threads.pdf". 
j'y explique les problèmes qui se sont posés à moi et les solutions pour les résoudre ou les choix temporaires effectués.

 Conclusion

Le projet n'est pas terminé. La génération automatique des fichiers de tests alourdit un peu le code...

Mon souci est de génerer une structure de code qui reste lisible dans le corps principal de la fiche. Le fait que mon traitement long figure totalement dans la méthode Execute ne me plait qu'à moitié.

En effet, dans le projet initial qui a motivé ce test, ça n'est pas un mais plusieurs traitements longs qui s'enchainent. Certains pourront s'exécuter simultanément mais d'autres devront attendre la fin d'autres séquences d'analyses...

Par ailleurs le contôle du clignotement et des différents Threads souffrent encore de quelques ratés. Donc le code reste à améliorer...

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture LISTES ÉNUMÉRÉES : CONCATÉNATION ET UTILISATION DES FONCTION...
Source avec Zip Source avec une capture GESTION D'UN TYPE ENUMÉRÉ DANS TLISTBOX
Source avec Zip Source avec une capture SPLIT PARTIES D'UN FICHIER ET PRODUCTION DE NOMS DE FICHIERS
Source avec Zip Source avec une capture LISTBOX TRANSPARENTE CRÉÉE DYNAMIQUEMENT SUR UNE IMAGE
Source avec Zip Source avec une capture GESTION DE CASES À COCHER PERSONNALISÉES DANS UN STRINGGRID

 Sources de la même categorie

Source avec Zip Source avec une capture EXEMPLE D'UTILISATION DWM API par CynicRus
Source avec Zip HUMAN-LIKE MOUSE MOVEMENTS par CynicRus
Source avec Zip UTILISER LES FICHIERS *.CPL par happy05
Source avec Zip Source avec une capture LISTES ÉNUMÉRÉES : CONCATÉNATION ET UTILISATION DES FONCTION... par Jean_Jean
Source avec Zip LECTURE DE LA MEMOIRE D'UN AUTRE PROCESSUS par Mokost

 Sources en rapport avec celle ci

Source avec Zip 1 MILLION DE PARTICULES ACCESSIBLES EN MOINS DE 100 MS... par blueperfect
Source avec Zip LECTEUR DE FICHIER MULTIMÉDIA RIFF par Bacterius
Source avec Zip Source avec une capture AUTO-COMPLÉTION D'UN CONTRÔLE DE SAISIE par Bacterius
Source avec Zip Source avec une capture LES VALUE'S FADERS par blueperfect
Source avec Zip Source avec une capture BAKTPACK (PACK DE COMPOSANTS BACTERIUS) par Bacterius

Commentaires et avis

Commentaire de Bacterius le 19/05/2012 13:18:50

Bonjour, ben je passais par ici et j'ai remarqué ta source! C'est beaucoup de boulot et je trouve ca très bien de faire des petits projets pour se familiariser avec différents concepts (et surtout le faire d'une manière organisée, particulièrement avec un PDF, chapeau!). Je suis moi-meme très interessé dans le calcul haute performance, donc faire fonctionner un modèle multi-threads efficacement est une des mes activités.

Quant au problème de l'erreur quand l'application se ferme, il faut faire attention que le thread ne soit pas en train d'executer du code VCL lorsque la fiche est détruite, sinon il lancera une violation d'accès. Il est en general utile de séparer les données utilisées par les differents threads dans une unité completement dissociée du code VCL (fiche, etc...). Idéalement un thread devrait pouvoir continuer a fonctionner sans fiche principale (sans l'affichage du progrès et autres, evidemment). En fait c'est le principe par lequel beaucoup d'applications utilitaires fonctionnent, ils lancent les threads "travailleurs" qui font leur boulot, et l'affichage de l'interface graphique est un choix qui est fait par l'utilisateur (par ligne de commande ou autre), les résultats des threads étant de toute facon écrits sur disque. Parfois chaque thread a sa propre fiche, mais je suis pas trop fan de ca.

Note qu'il est aussi possible de complètement contourner les appels a Synchronize et d'envoyer des messages Windows a la fiche principale a la place, ca peut parfois simplifier les choses (mais pas toujours!). Ca évite aussi naturellement le probleme de violation d'accès puisqu'au lieu d'essayer d'accéder a la fiche principale, il ne fera qu'envoyer un message a une fiche qui n'existe plus (ce qui ne produit aucune erreur).

Juste une remarque, il faudrait separer les threads et les petites procédures d'utilité dans des unités séparées ... c'est assez dur a lire en ce moment.

C'est tout pour le moment, c'est beaucoup de code et j'ai pas encore tout lu!

Commentaire de Jean_Jean le 19/05/2012 14:22:54

Salut Bactérius,

Merci pour tes commentaires très pertinents. Je suis d'accord avec toi pour presque tout. Me passer de la méthode synchronize serait un rêve, mais il ne faudrait pas que ça alourdisse de trop le code.

En fait j'ai écris ce code assez rapidement et ne voulais pas en faire une usine à gaz. C'est loupé! J'ai presque passé plus de temps sur le Pdf pour expliquer ce que je voulais faire. Le code se compliquait au fur et à mesure de mes essais.

Le prochain projet (j'ai encore plein de choses à expérimenter) tiendra compte de simplifications sur l'organisations en unités séparées.  Bien sûr j'essaierai de tenir compte de tes remarques...

A+

Commentaire de Jean_Jean le 20/05/2012 10:15:44

En fait, je vais faire une MAJ du projet 3 pour plus de lisibilité et essayer de régler quelques bugs!
Yo les delphistes!

Commentaire de ManChesTer le 21/05/2012 02:08:53 administrateur CS

Salut,

Une petite astuce qui fonctionne:

type
  MyThread = class(TThread)
  public
    constructor Create(CreateSuspended:boolean);
    destructor Destroy; override;
    ResultAdress:Longint;
    Resultat:Boolean;
  protected
    procedure Execute; override;
  end;


constructor MyThread.Create(CreateSuspended:boolean);
begin
  inherited Create(CreateSuspended);
  FreeOnTerminate:=false;
  Getmem(Mathread.ResultAdress,unbuffersize)
...
end;

destructor TPersoThread.Destroy;
begin
resultat:=false;
freemem(Mathread.ResultAdress);
inherited;
end;

procedure MyThread.Execute;
var sec : longint64;
begin
  repeat
    Sleep(100);
    strpcopy("Je tourne depuis "+inttostr(sec)+' Secondes");
    Resultat:=True;
  until Terminated;
end;


Procedure Tform1.LireDonees_MyThread; // depuis un ttimer par ex...
Begin
If Mythread.Resultat then
begin
  Form1.Caption:=Strpas(MyThread.ResultAdress);
  Mythread.Resultat:=false;
end;
end;

on peut aussi complexifié en utilisant par exemple des record ou autres...
l'usage de ReallocMem & co est permis mais ! aux synchros.
En bref ca évite d'utiliser les disques ou les msg intempestifs.

Bon Coding...

ManChesTer.

Commentaire de ManChesTer le 21/05/2012 02:11:46 administrateur CS

Heuu il faut lire :
  sec:=0;
  repeat
    Sleep(1000);
    strpcopy("Je tourne depuis "+inttostr(sec)+' Secondes");
    inc(sec)
    Resultat:=True;
  until Terminated;

Bon Coding...

ManChesTer.

Commentaire de ManChesTer le 21/05/2012 02:13:26 administrateur CS

Hmm décidement...

Le strpcopy vers le buffer évidement,


Bon Coding...

ManChesTer.

Commentaire de Jean_Jean le 21/05/2012 08:39:22

Yo Manchester,
  Heu si j'ai bien compris, d'après toi je dois inclure une gestion de la mémoire du Thread? Je pensai que c'était transparent... Bon je suis en train de réfléchir à la récriture du projet 3, je vais tester ta proposition.

C'est bizarre, je viens de déplacer simplement les threads dans une autre unité et je ne plus écrire if MonThread.Terminated dans ma fiche principale. Je  me contente donc du simple if Assigned(MonThread) then MyThread.Terminate;

Quant à ta remarque sur la durée du fonctionnement du Thread, c'est une idée que je pourrai exploiter tout simplement pour gérer la durée du clignotement de la LED.

Merci

Commentaire de blueperfect le 21/05/2012 22:11:54

Je prends le commentaire en cours de route :

Etant moi-même sur le problème, je ne m'attarde pas sur tes sources...

Ce que j'en relève, est cependant important :

D'abord Synchronize...
Tu peux l'éviter en gérant l'affichage d'une autre manière : avec le fameux TControlCanvas...
Tu lance un thread qui construit un TBitmap, et un autre qui toutes les 25ms utilise un TControlCanvas (et Lock/unlock) pour afficher ce TBitmap sur un control (qui peut être la fiche)... Plus de Invalidate, et pas de timer...plus de VCL intempestive...de plus, l'intérêt (le gain de vitesse) est surprenant lorsque les threads produisent eux-même des  "sous-bitmap'...

Pour ton erreur de fin de traitement : le thread DOIT checker Terminated (comme le dit la doc), mais lorsque tu quitte l'application (ce qui ferme la fiche), le thread n'est pas "terminated", et devient instable... Installe un système de sémaphore (un simple pointeur sur un booléen) que tu renseigne à vrai en sortie de Execute, ou dans DoTerminate...Ne quitte ta fiche que lorsque le flag est positionné (par une boucle while not(thread.StopFlag^) do Sleep(1); )...

Si tu comptes stocker et échanger des variables entre threads (des structures, des chaines, des variants...), regarde mon objet TVariables... Tout l'intérêt réside dans l'utilisation d'une TThreadList pour stocker les Variants...

@+

Commentaire de blueperfect le 21/05/2012 22:14:52

NB :
en plus de vérifier Terminated, ton thread devrait aussi checker ComponentState (de la fiche ou de Application), et quitter si sa valeur csDestroying est positionnée :

while not(self.Terminated) and (Forms.Application.ComponentState=Classes.csDestroying)
do .....;

@+

Commentaire de blueperfect le 21/05/2012 22:16:23

rectification :
'<>' pas '='

while not(self.Terminated) and (Forms.Application.ComponentState <> Classes.csDestroying)
do .....;

Commentaire de Jean_Jean le 22/05/2012 09:03:06

Merci BluePerfect pour tes remarques.

Elles méritent d'être étudiées et expérimentées. Je vais être obligé de diviser le code car il semble que l'on soit limité en taille à 1Mo pour les sources.

Avec tout ce que vous me dites, j'ai de quoi faire quelques sources encore...

A+

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Aide fichiers delphi [ par felina1 ] Bonjour à tous,Je cumul formation vb6 et delphi. VB6, je m'en sors à peu près, mais delphi....sans commentaires!Connaissez vous un bon site avec des Environnement de développement non sauvegardé [ par vivelesquads ] Bonjour,J'utilise Delphi 7 sous WinXP SP2. J'ai le problème suivant. Quand je quitte un projet son environnement (fichiers ouverts, breakpoints, ..) n Ajouter TColumn à un TListBox [ par christophedlr ] Bonjour à tous,Je voudrais savoir si il est possible d'ajouter un TColumn dans un TListBox, et si oui, comment je pourrais faire.Pour ceux qui me diro copie de fichiers excel???? [ par othland ] slt tlm;j'ai utilisé la fonction : CopyFile('C:\dell\exc001.xls','C:\dell\exc002.xls', FALSE);mais apparemment ça ne marche pas!y a t il une autre sol Liste de fichier (WEB) [ par l0sth34d ] Bonjour! :PJe suis entrain de travailler sur un auto-updater et voici la façon qu'il doit fonctionner... - Creer une liste de fichiers/dossiers qui so Formats des fichiers Vidéos et Audios [ par Francky23012301 ] Salut à tous,Suite aux sources déposés par Cirec et la question conceptuelle de Cari , je me suis interrogé sur la structure d'un JPEG. J'ai trouvé un Ecrire du texte dans un fichier binaire [ par christophedlr ] Bonjour à tous,Je suis entrain de faire un programme qui utilise les fichiers binaire.Pour faire le programme, j'ai opté pour l'utilisation de BlockRe boucle avec de gros traitements [ par saravana ] bjr a tous je suis en train de réaliser une visionneuse, jutilise  un stringlist qui contient le nom des fichiers,mais kan mes fichiers dépasses les 2 créer un ActiveX [ par askil2000 ] Bonjour, je travail avec delphi 7 version entreprise, et souhaiterais créer un ActiveX ou Contrôle ActiveX pour une application web simple (une fiche, Threads et events [ par Danonne ] Salut a tous.Après de nombreuses recherches sur divers sites et forums, je n'ai pas réussi à trouver une réponse (claire et précise) à ma question exi


Nos sponsors


Sondage...

CalendriCode

Mai 2013
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Photothèque

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,014 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales