В современном программировании на Delphi, особенно при разработке многозадачных приложений, важно уметь эффективно использовать ресурсы компьютера. Одним из способов достижения этого является использование параллельной библиотеки (Parallel Programming Library, PPL), которая предоставляет альтернативу традиционному подходу с использованием TThread и функцией sleep().
Проблема с TThread и sleep()
Использование TThread и sleep() в коде может привести к неэффективному использованию процессорного времени. Когда задача входит в цикл ожидания (например, sleep(100)), она блокирует поток, на котором выполняется, и другие задачи не могут использовать этот поток, пока первая задача не завершит свою работу или не освободит поток по таймауту.
Пример кода с TThread и sleep()
type
TObj = class
pos: Integer;
Done: Boolean;
constructor Create;
procedure DoWork(Sender: TObject);
end;
constructor TObj.Create;
begin
pos := 0;
Done := False;
end;
procedure TObj.DoWork(Sender: TObject);
begin
repeat
Inc(pos);
Sleep(100); // Задержка в 100 мс
until Done;
end;
procedure TForm1.StartClick(Sender: TObject);
var
i: Integer;
begin
// Инициализация и запуск задач
// ...
// Ожидание 5 секунд
Sleep(5000);
// Проверка результатов
// ...
end;
Решение с использованием PPL
PPL позволяет использовать модель потоков, которая автоматически управляется, и вы можете не заботиться о создании и управлении потоками вручную. Она включает в себя механизм пула потоков, который автоматически настраивается на основе количества доступных ядер процессора и текущей загрузки.
uses
System.Threading;
type
TObj = class(TInterfacedObject)
pos: Integer;
Done: Boolean;
procedure DoWork;
end;
constructor TObj.Create;
begin
pos := 0;
Done := False;
end;
procedure TObj.DoWork;
begin
repeat
Inc(pos);
Task.Yield; // Передача управления другим задачам
until Done;
end;
procedure TForm1.StartClick(Sender: TObject);
var
i, Count: Integer;
Tasks: TArray<ITask>;
begin
Count := 40;
SetLength(Tasks, Count);
for i := 0 to High(Tasks) do
begin
TObj.Create.DoWork := TTask.Create(TObj.Create, TObj.DoWork);
Tasks[i].Start;
end;
// Ждем завершения всех задач
TTask.WaitForAll(Tasks);
end;
Настройка пула потоков
Если вам необходимо более тонкое управление потоками, вы можете создать объект TThreadPool, установить свойства MinWorkerThreads и MaxWorkerThreads, и передать этот объект в конструктор TTask.
var
ThreadPool: TThreadPool;
begin
ThreadPool := TThreadPool.Create;
ThreadPool.MinWorkerThreads := 4;
ThreadPool.MaxWorkerThreads := 8;
// Используем ThreadPool в конструкторе TTask
end;
Заключение
Использование PPL позволяет избежать проблем, связанных с блокировкой потоков при помощи sleep(). Вместо этого, вы можете использовать Task.Yield для передачи управления другим задачам, что позволяет пулу потоков более эффективно распределять задачи между доступными потоками. Это приводит к повышению общей производительности многозадачных приложений на Delphi.
Улучшение производительности многозадачных приложений на Delphi достигается за счет использования параллельной библиотеки, которая предлагает альтернативу традиционным `TThread` и функции `sleep()`, позволяя более эффективно управлять потоками и ресурсам
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.