powered by simpleCommunicator - 2.0.30     © 2024 Programmizd 02
Map
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Многопоточное программирование в Delphi для начинающих
25 сообщений из 160, страница 2 из 7
Многопоточное программирование в Delphi для начинающих
    #39977663
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dmitry Arefiev
Хорошо работающая PPL это благо для начинающих (и не только).
Либо заголовок не правильный, либо план учебника ...


Возможно в будущем появятся разделы, посвящённые PPL. Тем более PPL все активнее вторгается в нашу жизнь :) Но и помимо PPL есть много тем, которые хотелось бы описать (например, руки пока не дошли до описания темы синхронизации между потоками, а это, я считаю, очень важно). Но благодаря реализации функции ThreadWaitTimeout удаётся до последнего оттягивать такую сложную для понимания тему, как эвенты.
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39977664
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dmitry Arefiev
DmSer
Оказывается ...

Так ты знаешь PPL или только TThread ? :)


Я изучал довольно много материала по PPL, смотрел видео-уроки, проводил некоторые эксперименты, так что считаю, что знаю о ней достаточно много.
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39977677
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer
X-Cite
Код: pascal
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.Button2Click(Sender: TObject);
var
  x: ITask;
begin
  x := TTask.Run(
    procedure
    var
      a: TArray<Byte>;
    begin
      for var k := 1 to 3 do
      begin
        SetLength(a, 1024 * 1024 * 500);
        FillChar(a[0], 1024 * 1024 * 500, 5);
        if TTask.CurrentTask.Status = TTaskStatus.Canceled then
          Exit;
        TFile.WriteAllBytes('C:\TTask.txt', a);
      end;
    end
  );
  while x.Status <> TTaskStatus.Running do
    ; // Убеждаемся что задача начала выполнятся
  x.Cancel();
  Application.Terminate();
end;


.


И тут блестящая PPL разом превратилась в тыкву! Оказывается, как и с TThread, нужно останавливать таски перед завершением программы, а в таске проверять необходимость завершения :)


Это еще не идёт речь о том, что часто потоки нужно завершать в определенном порядке. Как это сделать с тасками - объяснить начинающему программисту будет проблематично :)
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39977688
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer
(имею ввиду прежде всего GoLang) в сто раз меньше связанных с многопоточностью проблем и граблей, чем в языке Delphi. А теперь им еще и шедулер улучшили!

ты про шедулершедулер или gc?
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39977701
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дегтярев Евгений
DmSer
(имею ввиду прежде всего GoLang) в сто раз меньше связанных с многопоточностью проблем и граблей, чем в языке Delphi. А теперь им еще и шедулер улучшили!

ты про шедулершедулер или gc?


Раньше кооперативный планировщик был, а работу планировщика ОС они грубо говоря игнорировали. Теперь учитывают.
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39977717
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock

Это еще не идёт речь о том, что часто потоки нужно завершать в определенном порядке. Как это сделать с тасками - объяснить начинающему программисту будет проблематично :)


Опять путаница между теплым и мягким.

Есть различные задачи, которые надо реализовать.
Эти все задачи можно и нужно отнести к определенным классам задач.
И здесь вступает в игру то, что для разных классов задач, подходят разные решения.

Если говорить о Delphi, то для класса задач асинхронного ожидания ответа или исполнения лучше подходят TTask.
Для класса задач распараллеливания лучше подходит TParallel.
Для класса задач фонового (долгого, постоянного, возможно на время жизни всего приложения) выполнения (То о чем тут чаще всего говорят) к сожалению нет никакого BackgroundService который бы умел и зависимости разруливать и шедулер иметь нормальный и прочее, но из того что есть лучше подходит как раз TThread.

На самом деле TThread - это класс для выполнения фоновых (долгоиграющих) задач.

Если говорить о теме топика, то я не понимаю что такое многопоточное программирование. Есть решение задач с помощью потоков - это уже звучит по другому. И как минимум понятно, что не все задачи можно и нужно решать с помощью потоков.
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39977880
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer
Дегтярев Евгений
пропущено...
ты про шедулершедулер или gc?

Раньше кооперативный планировщик был, а работу планировщика ОС они грубо говоря игнорировали. Теперь учитывают.

видимо у авторов были веские причины запилить это, но как по мне оно решает настолько нетипичную для гошного кода ситуацию
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39977947
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня ощущение, что многие критикующие пропустили важные слова - "для начинающих".
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39977984
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite
Если говорить о теме топика, то я не понимаю что такое многопоточное программирование. Есть решение задач с помощью потоков - это уже звучит по другому. И как минимум понятно, что не все задачи можно и нужно решать с помощью потоков.
Это умение "сшивать" взаимодействие потоков и знать как использовать различные способы синхронизации. А что-то там считать - ничем от однопоточного не отличается
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39977988
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite
Проблема в Дельфи в том, что разработчики которые туда пытаются придти учатся по книжкам которые написаны были во времена высокого порога входа в программирование, а не когда курсы клепают по 100 "программистов" в день...

Поэтому лучше, чтобы появлялись книжки, которые позволят вчерашним студентам, которые не знают как там работает под капотом, да и не надо им знать, но которые будут эффективно решать реальные бизнес-задачи используя современные инструменты.

1. проблема в том, что такие "программисты" никому и не нужны - если они не чисто за корочкой идут
2. нету реальных бизнес-задач с потоками, которые могут решать "прошедшие курсы" :-)
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39977993
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman
У меня ощущение, что многие критикующие пропустили важные слова - "для начинающих".

просто пиписьками меряются друг перед другом. Другого объяснения нет
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39977998
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer,
я не уверен, но может быть при ручном убиении потока кошернее делать экземпляру потока не просто Free, а Free + Nil?

Я обычно провожу проверку на существование предыдущего экземпляра прежде, чем запустить новый, типа:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
type
Form1 = class(TForm)
...
private
FMyThread: TMyThread;
...
end;

procedure Button1Click...
begin
  //если сделать просто FMyThread.Free, то праздника не получится
  if Assigned(FMyThread) the Exit;
  ...
end;
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39978161
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док
DmSer,
я не уверен, но может быть при ручном убиении потока кошернее делать экземпляру потока не просто Free, а Free + Nil?

Я обычно провожу проверку на существование предыдущего экземпляра прежде, чем запустить новый, типа:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
type
Form1 = class(TForm)
...
private
FMyThread: TMyThread;
...
end;

procedure Button1Click...
begin
  //если сделать просто FMyThread.Free, то праздника не получится
  if Assigned(FMyThread) the Exit;
  ...
end;



Конечно, так и нужно. А в каком примере nil отсутствует? Вроде следил, чтобы везде было!
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39978165
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer
А в каком примере nil отсутствует?

Код: pascal
1.
2.
3.
4.
5.
6.
7.
procedure TForm1.FormDestroy(Sender: TObject);
begin
  // При закрытии программы необходимо завершить работу потока
  // и уничтожить объект потока MyThread
  if MyThread <> nil then
    MyThread.Free;
end;


стр 16
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39978195
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док
DmSer
А в каком примере nil отсутствует?

Код: pascal
1.
2.
3.
4.
5.
6.
7.
procedure TForm1.FormDestroy(Sender: TObject);
begin
  // При закрытии программы необходимо завершить работу потока
  // и уничтожить объект потока MyThread
  if MyThread <> nil then
    MyThread.Free;
end;


стр 16


Здесь нормально, тут же FormDestroy! Есть примеры, где объект потока уничтожается при нажатии на кнопку, вот там ссылка обнуляется и есть объяснение зачем это делается.
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39978490
Bred eFeM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer,
Респект за работу!

Рекомендую назвать материал - "Памятка изучающим (многопоточное программирование на) Delphi TThread"

(руки пока не дошли до описания темы синхронизации между потоками, а это, я считаю, очень важно).
Мдя... (может рассказать о нескольких способах кормления философов на примерах?)
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39978532
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bred eFeM
Мдя... (может рассказать о нескольких способах кормления философов на примерах?)


Я не уверен в пользе такого подхода. Помню, на 2-м или 3-м курсе университета были занятия, на которых преподавали многопоточность по философам ( библиотека Gala ), анимация интересная, но вряд ли кто-то из студентов смог извлечь из неё что-то полезное. А преподаватель вообще был не знаком с этой библиотекой :)
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39984742
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Учебник сохранён в формате markdown. Очень удобная вещь оказалась. Текст в итоге читается вроде не хуже, чем в docx. ссылка
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39984773
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не понравилось буквально в первом примере это:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure TMyThread.Execute;
var
  V: Int64;
begin
  FreeOnTerminate := True;
  V := DoLongCalculations;
  MyShowMessage('Результат: ' + IntToStr(V));
end;


Как только начинающий захочет заменить MyShowMessage на показ своей супер-пупер формы - он может нехило обломаться. Обязательно надо подчеркнуть что все UI вещи (по крайней мере VCL) надо выполнить в Synchronize или Queue. Понятно что в примере голый WinApi и там и так прокатит, но лучше сразу показать. Вместо апишного вызова лучше взять делфёвый ShowMessage
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39984786
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
white_nigger
Не понравилось буквально в первом примере это:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure TMyThread.Execute;
var
  V: Int64;
begin
  FreeOnTerminate := True;
  V := DoLongCalculations;
  MyShowMessage('Результат: ' + IntToStr(V));
end;


Как только начинающий захочет заменить MyShowMessage на показ своей супер-пупер формы - он может нехило обломаться. Обязательно надо подчеркнуть что все UI вещи (по крайней мере VCL) надо выполнить в Synchronize или Queue. Понятно что в примере голый WinApi и там и так прокатит, но лучше сразу показать. Вместо апишного вызова лучше взять делфёвый ShowMessage


В пояснении к этому примеру приводится необходимая информация о MyShowMessage и ShowMessage. Это сделано специально, чтобы читатель не пытался вызывать ShowMessage из доп. потока.
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39984976
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пробежал по диагонали. Классная статья получилась. Для полноты картины еще бы неплохо добавить разделы про эвенты, мьютексы, семафоры. Я, например, про эвенты кое-как наскреб инфу в инете, потому методом проб и ошибок дотумкал, как они работают :)
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39985017
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док
Пробежал по диагонали. Классная статья получилась. Для полноты картины еще бы неплохо добавить разделы про эвенты, мьютексы, семафоры. Я, например, про эвенты кое-как наскреб инфу в инете, потому методом проб и ошибок дотумкал, как они работают :)


Спасибо!

Эвенты, мьютексы и семафоры - очень сложная часть. Пока не придумал, как это влить в статью. Мьютексы может сейчас и не особенно актуальны. На своей практике могу сказать, что мьютексы полезны в случае, если нужно синхронизировать работу нескольких экземпляров программы (в том числе реализовать контроль повторного запуска приложения). В рамках одной программы они не нужны, можно их заменить крит. секцией либо TMonitor. Эвенты чаще используем, но только в рамках одной программы (т.е. без межпроцессного взаимодействия). В основном в обмене по RS-232. TMonitor их также может заменить. Семафоры вообще не используем, имхо, проще использовать крит.секцию + счётчик чем разбираться с ещё одним объектом синхронизации.
Нужно ещё учитывать кроссплатформенность, иначе можно кучу времени потратить на то, что является сложным, windows-ориентированным и никому не нужным.

Раньше я очень часто использовал эвенты, мьютексы, может даже злоупотреблял ими в какой-то степени. Сейчас гораздо реже. Выяснилось, что очень многие вещи можно сделать на крит. секции и циклах ожидания со Sleep :). Может так получается небольшой оверхед, но программа становится проще.
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39985028
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer и, как минимум, реализовать override-метод Execute.
и, как минимум, переопределить виртуальный метод Execute.


DmSer⚠️ Запущенный поток не завершается при выходе из программыЗавершается
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
procedure _Halt0;
........
{$IF Defined(MSWINDOWS)}
      ExitProcess(ExitCode);
{$ELSEIF Defined(POSIX)}
      __exit(ExitCode);
{$ELSE}
{$MESSAGE ERROR 'Unknown platform'}
{$ENDIF}
      // never arrive hear.
    end;

    InitContext := InitContext.OuterContext^
  end;
end;

Но до выделенной строки дело может не дойти из-за финализации менеджера памяти.

Но я о чем - в Windows процесс живет, пока работает хотя бы один поток процесса, тогда как Delphi принудительно убивает процесс при завершении главного потока

DmSerВаша программа с большой вероятностью будет глючить.Может имеет смысл обойтись без сленга?

DmSerТакже хочу отметить, что при срабатывании таймера не следует обращаться к базе данных из основного потока, лучше это делать из дополнительного потока, разумеется, в отдельном подключении .Если мы говорим о мануале для новичков, то нифига это не разумеется. Если уже зацепил работу с БД, то явно укажи, что делать только так или смотреть документацию к СУБД. Тот же MySQL позволяет расшаривать соединение между потоками, при выполнении определенных условий

DmSerℹ️ Внимание! Если периодическая задача выполняется редко (например, каждые 10 минут), рекомендуется каждый раз (если это не сложно!) для такой задачи создавать новый поток. Вероятно, это лучше, чем часами удерживать дополнительный поток в спящем состоянии (особенно, если вы разрабатываете 32-разрядное Windows-приложение).Чем лучше? Я бы наоборот делал бы обратную рекомендацию. Спящий поток есть не просит, а снаружи лучше управлять одним объектом, чем каждый раз создавать новый. Плюс дополнительное время на инициализацию нового потока


DmSer⚠️ Внимание! Если поток переведён в спящее состояние с помощью функции Sleep, то не существует другого способа выйти из этого состояния кроме истечения указанного временного периодаТак зачем учить плохому? Есть две функции, которые можно использовать исключительно в тестовых приложениях и никогда в реальных Sleep() и Application.ProcessMessages. Новичкам об этих функциях вообще лучше не знать
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39985029
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer
Код: pascal
1.
2.
3.
4.
5.
6.
7.
procedure TForm1.FormDestroy(Sender: TObject);
begin
  // При закрытии программы необходимо завершить работу потока
  // и уничтожить объект потока MyThread
  if MyThread <> nil then
    MyThread.Free;
end;

Ну и в чем великий смысл выделенной строчки? Если
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
procedure TObject.Free;
begin
// under ARC, this method isn't actually called since the compiler translates
// the call to be a mere nil assignment to the instance variable, which then calls _InstClear
{$IFNDEF AUTOREFCOUNT}
  if Self <> nil then
    Destroy;
{$ENDIF}
end;
...
Рейтинг: 0 / 0
Многопоточное программирование в Delphi для начинающих
    #39985042
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSerЕсли же мы решим объявить для такого потока переменную и будем пытаться с нею работать, то рискуем нарваться на ошибку доступа к памяти «Access Violation», поскольку объект потока может быть уничтожен в любой момент времени.Верно только для случая, когда поток завершается сам
...
Рейтинг: 0 / 0
25 сообщений из 160, страница 2 из 7
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Многопоточное программирование в Delphi для начинающих
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]