Tutoriel : Utilisation des tâches de la bibliothèque de programmation parallèle

De RAD Studio
Aller à : navigation, rechercher

Remonter à Tutoriels Bibliothèque de programmation parallèle

Ce tutoriel explique comment implémenter une application en utilisant les tâches de la bibliothèque de programmation parallèle (PPL). Ces tâches sont des unités de travail qui se trouvent dans la file d'attente et qui démarrent lorsque le temps CPU est disponible. Les tâches peuvent exécuter des opérations en parallèle. Un thread maître gère cette file d'attente et alloue des threads à partir du pool de threads pour qu'ils exécutent les tâches. Ce pool de threads comporte un nombre de threads dépendant du nombre de CPU disponibles.

Création du projet

Créez un nouveau projet :

  • Pour Delphi, choisissez Fichier > Nouveau > Application multi-périphérique - Delphi > Application vide.
  • Pour C++Builder, choisissez Fichier > Nouveau > Application multi-périphérique - C++Builder > Application vide.

Ajout des composants

  1. Ajoutez un composant TButton et un composant TLabel à la fiche. TButton démarrera une tâche et TLabel affichera les résultats.
  2. Déposez un composant TScrollBar sur la fiche.
  3. Déposez un TFloatAnimation sur la fiche.
    • Imbriquez le TFloatAnimation sous la barre de défilement. La structure des composants doit ressembler à ceci :
    Structure task.png
    • Définissez la propriété AutoReverse sur True.
    • Définissez la propriété Duration sur 1 seconde.
    • Définissez la propriété Enabled sur True.
    • Définissez la propriété Loop sur True.
    • Définissez la propriété PropertyName sur Value.
    • Définissez la propriété StartValue sur 0 et la propriété StopValue sur 100.

Implémentation des gestionnaires d'événement pour les composants

Commencez par implémenter le gestionnaire d'événement pour l'événement OnClick de TButton. Pour cela, écrivez le code comme suit :

Delphi :
procedure TForm1.Button1Click(Sender: TObject);
var
  lValue: Integer;
begin
    Label1.Text := '--';
    {Some calculation that takes time}
    Sleep(3000);
    lValue := Random(10);
    Label1.Text := lValue.ToString;
end;
end.
C++ :
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	int lValue;
	Label1->Text = "--";
	//{Some calculation that takes time}
	Sleep(3000);
	lValue = Random(10);
	Label1->Text = String(lValue);

}

Ce code est un exemple d'un long processus de calcul qui démarre lorsque vous appuyez sur le bouton. Il suspend les opérations pendant 3 secondes (veille) puis affiche un numéro aléatoire entre 0 et 10.

Exécution de l'application sans l'implémentation de la PPL

A ce stade, vous pouvez exécuter l'application :

  • Appuyez sur F9 ou choisissez Exécuter > Exécuter.
Run1.png

Vous voyez la barre de défilement se déplacer de gauche à droite. Mais dès que vous appuyez sur le bouton et que le long calcul démarre, la barre de défilement s'arrête jusqu'à ce que le calcul soit terminé. Ce n'est évidemment pas le comportement attendu. C'est pourquoi la section suivante explique comment améliorer ce comportement en utilisant la fonctionnalité TTask de la PPL.

Implémentation de la fonctionnalité TTask

Cette section explique comment intégrer le long calcul (implémenté en tant qu'événement OnClick) dans une classe TTask pour que ce processus puisse s'exécuter en parallèle.

D'abord, à l'aide de la fiche précédente de l'application, renommez les composants TButton et TLabel en tant que ButtonTask1 et LabelTask1 respectivement.

Puis, incluez la bibliothèque PPL dans le projet :

Pour les applications Delphi, ajoutez l'unité suivante à la clause uses, si elle n'est pas présente :
uses
  System.Threading;
Pour les applications C++, ajoutez l'opérateur include suivant dans le fichier d'en-tête du projet :
#include <System.Threading.hpp>

Pour exécuter le processus de calcul en tant que tâche, la PPL fournit la méthode TTask.Run. Pour ce faire, modifiez et écrivez le code comme suit :

Delphi :
procedure TForm1.ButtonTask1Click(Sender: TObject);
var
  lValue: Integer;
begin
    Label1.Text := '--';
    TTask.Run(procedure
      begin
          {Some calculation that takes time}
          Sleep(3000);
          lValue := Random(10);
          TThread.Synchronize(nil,
            procedure
            begin
                  Label1.Text := lValue.ToString;
            end);
      end);
end;

Le code ci-dessus utilise une méthode anonyme pour effectuer le long calcul, mais il existe différentes options de paramètres d'entrée possibles avec la méthode TTask.Run dans Delphi.

C++ :

Incluez également le code pour les classes TCppSync et TCppTask :

class TCppSync : public TCppInterfacedObject<TThreadProcedure> {
	int &lValue;
	TLabel *Label;
public:
	TCppSync(int &l, TLabel *lbl):lValue(l),Label(lbl)
	{}
	void __fastcall Invoke(){
	   Label->Text = String(lValue);
	}
};
 class TCppTask : public TCppInterfacedObject<TProc> {
	 int &lValue;
	 TLabel *Label;
 public:
	TCppTask(int &l, TLabel *lbl): lValue(l), Label(lbl)
	{}
	void __fastcall Invoke(){
		Sleep(3000);
		lValue = Random(10);
		TThread::Synchronize(0,_di_TThreadProcedure(new TCppSync(lValue, Label)));
	}
 };
void __fastcall TForm1::ButtonTask1Click(TObject *Sender)
{
	LabelTask1->Text = "--";
	TTask::Run(_di_TProc(new TCppTask(lValue, LabelTask1)));
}

Ajoutez la déclaration de lValue dans la section private du fichier d'en-tête :

private:	// User declarations
	int lValue;

Le code ci-dessus utilise un type TProc pour effectuer le long calcul, mais il existe différentes options de paramètres possibles avec la méthode TTask.Run dans C++.

Exécution de l'implémentation de la fonctionnalité TTask

A ce stade, vous pouvez exécuter l'application :

  • Appuyez sur F9 ou choisissez Exécuter > Exécuter.

Dans ce cas, lorsque vous appuyez sur le bouton ButtonTask1, vous pouvez voir que l'action scrollBar reste active et n'est pas interrompue. Donc, en utilisant la fonctionnalité TTask de la PPL, vous pouvez exécuter plusieurs tâches en parallèle.

Voir aussi