Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
-11 / 9 / 1
Регистрация: 20.06.2021
Сообщений: 790
RAD 2009-XE2

Как подождать завершения потоков ?

07.10.2023, 12:10. Показов 4318. Ответов 69
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здрасте, пишу свой .pas модуль он подразумевает многопоточность, подскажите пожалуйста как правильно подождать пока все потоки не завершаться, перерыл весь интернет ничего нормально работающего не нашёл кроме такого костыля с Win32Check который так же работает через раз к сожалению:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
unit testlib;
 
interface
 
uses
  SysUtils,
  Classes,
  System.syncobjs,
  windows,
  System.Generics.Collections;
 
type
 Ttestlib= class
private
published
function Testy(const threads:integer): string;
constructor Create;
destructor Destroy; override;
end;
 
type
th = class(TThread)
private
protected
  procedure Execute; Override;
public
  constructor create(createsuspended:boolean);
end;
 
var
work:boolean=true;
Event: THandle;
cs:TcriticalSection;
 
implementation
 
{ th }
 
constructor th.create(createsuspended: boolean);
begin
inherited Create(CreateSuspended);
FreeOnTerminate := True;
end;
 
procedure th.Execute;
begin
inherited;
while work do begin
cs.Enter;
//КОД
cs.Leave;
if work then begin
//КОД
end;
end;
end;
 
{ Ttestlib }
 
constructor Ttestlib.Create;
begin
//Создадим нужные компоненты
end;
 
destructor Ttestlib.Destroy;
begin
inherited;
work:=False;
//Освободим Нужные компоненты
end;
 
function Ttestlib.Testy(const threads:integer): string;
var
i:integer;
thrs:th;
begin
Result:='';
ResetEvent(Event);
for I := 0 to threads-1 do begin
thrs:=th.create(False);
// Костыль ожидания завершения всех потоков:
Win32Check(DuplicateHandle(
      GetCurrentProcess,
      thrs.Handle,
      GetCurrentProcess,
      @Event,
      0,
      False,
      DUPLICATE_SAME_ACCESS
    ));
  end;
thrs.FreeOnTerminate:=True;
WaitForSingleObject(Event, INFINITE); // Само ожидание
CloseHandle(Event);
Result:='ГОТОВО';
end;
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.10.2023, 12:10
Ответы с готовыми решениями:

Как подождать завершения нескольких потоков, и если после минуты не завершились продолжать выполнение?
Как подождать завершения нескольких потоков, и если после минуты не завершились продолжать выполнение программы дальше?

Как подождать завершения приложения (по имени окна)
Бывает что мы запускаем какую та программу программно и нужно дождаться ее завершения. Можно конечно отслеживать процесс и т.п. или имя...

Как дождаться завершения всех работающих потоков?
type th = class(TThread) private public protected constructor Create(createsuspended:boolean); procedure Execute;...

69
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
08.10.2023, 19:35
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от AzAtom Посмотреть сообщение
Но проблем не вижу. Можно просто поставить проверку, не начинать обработку нажатия кнопки "Старт", если есть работающие потоки.
В моем случае никакой кнопки "Старт" нет. Крутится непрерывный процесс расчета минимального расстояния для пар объектов, которые каждый цикл смещаются. Объектов может быть до 1000, для каждой пары нужно посчитать расстояние, затем, начиная от самого минимального, определить все пары.
В однопоточном режиме с трудом обсчитывается до 100 объектов, с пулом потоков - уже до 1000.
И вот пока фоновые потоки пыхтят, новый цикл перемещения начинать нельзя))))

Добавлено через 1 минуту
Цитата Сообщение от Beltar Посмотреть сообщение
Т. е. обработчик должен завершиться до того, как потоки снова вызовутся. А мы знаем, они вызовутся? Может там какие-то операции по нажатию кнопки, а потом нужно стату вывести на экран и снова готов вкалывать. А может в игре что-то в игровом цикле, т. е. таймер прост бред.
Вот и я о том же.
Вешать обработчик, чтобы отслеживать состояние других обработчиков?
0
-11 / 9 / 1
Регистрация: 20.06.2021
Сообщений: 790
08.10.2023, 20:00  [ТС]
Цитата Сообщение от AzAtom Посмотреть сообщение
Нет. То есть, программа должна быть заблокирована?
Да именно программа должна уйти в лок (зависнуть) пока не выйдет ожидание WaitFor например и вот по завершению уже добавится строка в Мемо =)
То есть из ассинхронного вызова должен получится синхронный )
0
пофигист широкого профиля
4770 / 3207 / 862
Регистрация: 15.07.2013
Сообщений: 18,615
09.10.2023, 02:15
Цитата Сообщение от Uefi220 Посмотреть сообщение
Да именно программа должна уйти в лок (зависнуть) пока не выйдет ожидание WaitFor например и вот по завершению уже добавится строка в Мемо =)
То есть из ассинхронного вызова должен получится синхронный )
Имхо бред.
0
 Аватар для krapotkin
6854 / 4680 / 1465
Регистрация: 14.04.2014
Сообщений: 20,684
Записей в блоге: 21
09.10.2023, 07:26
если есть какие-то процессы, без которых программа не может идти "вперед", это совсем не значит, что она должна зависнуть.
она должна просто вырубить лишний интерфейс

Представим, у нас есть условный Телеграм.
При скачивании сразу нескольких видео (в фоновом режиме) вся программа останавливается и вы тихонько ждете, когда там все скачается.
Нет. Вовсе нет. Потоки работают, ГП тоже работает, даже если из рабочих частей там только кнопка Выход.
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
09.10.2023, 08:37
Цитата Сообщение от krapotkin Посмотреть сообщение
Нет. Вовсе нет. Потоки работают, ГП тоже работает, даже если из рабочих частей там только кнопка Выход.
Это все понятно.
Вопрос в том, как организовать именно ожидание, если оно нужно.
0
Модератор
4153 / 2362 / 814
Регистрация: 15.11.2015
Сообщений: 9,496
09.10.2023, 08:54
Цитата Сообщение от Uefi220 Посмотреть сообщение
Да именно программа должна уйти в лок (зависнуть) пока не выйдет ожидание WaitFor например и вот по завершению уже добавится строка в Мемо =)
Мне казалось, в моём примере именно так и происходит - добавление строки в Memo по завершении всех потоков. Ну а заблокировать и разблокировать при этом кнопку Старт - проще простого.
0
 Аватар для krapotkin
6854 / 4680 / 1465
Регистрация: 14.04.2014
Сообщений: 20,684
Записей в блоге: 21
09.10.2023, 08:59
три поста как организовать ожидание, с кодом
и новый вопрос - как организовать ожидание.
а это тогда что?
если надо просто подвесить программу, просто пишем поток.WaitFor()
https://docwiki.embarcadero.co... ad.WaitFor

Добавлено через 2 минуты
ВО!
а еще можно просто сделать

Delphi
1
2
3
th := TMyThread.Create(true);
th.Execute
th.Free;
и гордость от использования потока есть
и поток исполняется как надо, залочивая программу))
1
-11 / 9 / 1
Регистрация: 20.06.2021
Сообщений: 790
09.10.2023, 09:14  [ТС]
Цитата Сообщение от krapotkin Посмотреть сообщение
если надо просто подвесить программу, просто пишем поток.WaitFor()
При поток.WaitFor ошибка выкатится почти сразу Неверный Дескриптор(6)
0
 Аватар для Beltar
1072 / 513 / 41
Регистрация: 05.05.2022
Сообщений: 3,638
09.10.2023, 10:22
Кстати, а кто мешает в каждом из потоков по завершении проверять весь пул потоков, и если поток обнаружит, что он последний, то сделает еще какую-то работу?
0
 Аватар для krapotkin
6854 / 4680 / 1465
Регистрация: 14.04.2014
Сообщений: 20,684
Записей в блоге: 21
09.10.2023, 10:40
Delphi
1
2
3
4
5
6
7
8
9
10
procedure TForm5.b1Click(Sender: TObject);
begin
  th := TMyThread.Create(true);
  th.Start;
  th.WaitFor;
end;
procedure TMyThread.Execute;
begin
    sleep(10000);
end;
проверил

Добавлено через 1 минуту
Цитата Сообщение от Beltar Посмотреть сообщение
кто мешает
архитектура
когда все обо всех все знают, нет никакого разделения ответственности

если поток А получил ссылку на поток Б, то когда Б уничтожится, А получит по ссылке AV
чтобы этого не произошло, нужно еще один слой проверок монтировать
1
-11 / 9 / 1
Регистрация: 20.06.2021
Сообщений: 790
09.10.2023, 10:47  [ТС]
Цитата Сообщение от krapotkin Посмотреть сообщение
проверил
Я понял если в create FreeOnTerminate=False то поток.waitfor вроде работает, а можно ли сделать c FreeOnTerminate=True ?=)
0
Модератор
4153 / 2362 / 814
Регистрация: 15.11.2015
Сообщений: 9,496
09.10.2023, 11:13
Цитата Сообщение от Uefi220 Посмотреть сообщение
а можно ли сделать c FreeOnTerminate=True ?
Зачем? Если ты сделал поток.WaitFor и дождался завершения потока, значит, у тебя есть на него ссылка и можешь сам сделать ему поток.Free.
0
-11 / 9 / 1
Регистрация: 20.06.2021
Сообщений: 790
09.10.2023, 12:00  [ТС]
Цитата Сообщение от AzAtom Посмотреть сообщение
и дождался завершения потока, значит, у тебя есть на него ссылка и можешь сам сделать ему поток.Free.
Да это понятно, но для самообразования )
0
Модератор
4153 / 2362 / 814
Регистрация: 15.11.2015
Сообщений: 9,496
09.10.2023, 12:24
Uefi220, скорее, для самобичевания. В таком случае поток может завершиться до вызова WaitFor, и тогда получим исключение в лучшем случае.
0
-11 / 9 / 1
Регистрация: 20.06.2021
Сообщений: 790
09.10.2023, 19:33  [ТС]
Цитата Сообщение от AzAtom Посмотреть сообщение
WaitFor, и тогда получим исключение в лучшем случае.
Правильно ли будет вот так:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
type
th = class(TThread)
private
protected
  procedure Execute; Override;
public
  constructor create(createsuspended:boolean);
end;
 
constructor th.create(createsuspended: boolean);
begin
inherited Create(CreateSuspended);
FreeOnTerminate := False;
end;
 
function Ttestlib.Testy(const threads:integer): string;
var
i:integer;
thrs:th;
begin
Result:='';
for I := 0 to threads-1 do
thrs:=th.create(False);
thrs.WaitFor;
thrs.free;
Result:='Готово!';
end;
Или всё же нужно использовать массив потоков array of th ?
Боюсь просто не вся память будет освобождена ?
0
Модератор
4153 / 2362 / 814
Регистрация: 15.11.2015
Сообщений: 9,496
09.10.2023, 19:57
Цитата Сообщение от Uefi220 Посмотреть сообщение
Правильно ли будет вот так:
Нет. Тут только ожидание последнего созданного потока и его уничтожение. Даже если добавить begin ... end, то потоки будут запускаться строго друг за другом, и смысл использования потоков теряется.
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
09.10.2023, 20:27
Цитата Сообщение от Uefi220 Посмотреть сообщение
Или всё же нужно использовать массив потоков array of th ?
Если нужно ждать, или как-то управлять потоками, то массив.
И нужно понимать разницу - экземпляр TThread - это одно, а поток, который он создает - это другое.
И память, которая освобождается при помощи thrs.free, это память выделенная под экземпляр (не под поток).
0
-11 / 9 / 1
Регистрация: 20.06.2021
Сообщений: 790
09.10.2023, 21:53  [ТС]
Цитата Сообщение от AzAtom Посмотреть сообщение
Нет. Тут только ожидание последнего созданного потока и его уничтожение.
Я понял скорее всего так:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
type
th = class(TThread)
private
protected
  procedure Execute; Override;
public
  constructor create(createsuspended:boolean);
end;
 
constructor th.create(createsuspended: boolean);
begin
inherited Create(CreateSuspended);
FreeOnTerminate := True;
end;
 
function Ttestlib.Testy(const threads:integer): string;
var
i:integer;
thrs:th;
begin
Result:='';
for I := 0 to threads-1 do
thrs:=th.create(False);
thrs.FreeOnTerminate:=False;
thrs.WaitFor;
thrs.Free;
Result:='Готово!';
end;
Последнему потоку отключаем самоуничтожение, а остальным включаем в Create, так как последний уничтожаем вручную
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
09.10.2023, 22:51
Цитата Сообщение от Uefi220 Посмотреть сообщение
Последнему потоку отключаем самоуничтожение, а остальным включаем в Create, так как последний уничтожаем вручную
А если последний завершится раньше, чем любой из предыдущих?
0
 Аватар для krapotkin
6854 / 4680 / 1465
Регистрация: 14.04.2014
Сообщений: 20,684
Записей в блоге: 21
09.10.2023, 23:38
я теряю интерес. каждый уже по два раза написал, как НАДО
но мы уже который раз рассматриваем какие-то измышления в стиле "а вот если..."
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
09.10.2023, 23:38

Ожидание завершения потоков
Подскажите пж. как дождатся окончание выполнения потоков в unit-2 и потом продолжить в unit-3 чет не получается с условием так как в 22...

Ожидание завершения работы потоков
допустим есть программа, которая многопоточно отправляет get запросы через idhttp сначала на первый адрес из списка, затем на второй, на...

Как подождать ShellExecute?
Запускаю WinRar таким образом: //делит на указанные части procedure divisionFile(FileNameIn, FileNameOut: string; sizedivision:...

Как подождать завершения Task?
Есть WPF приложение, в нем в определённый момент запускается такая штука: Task fillTable = new Task(() => { ...

Как подождать завершения потока
Добрый день вот такое дело. не Могу РАЗОБРАТЬ ПРИНЦИП ОЖИДАНИЯ завершения потоков. Т.е. запустили мы 4 потока для 4 ядерного цпу и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
Модель по догадкам
anaschu 25.08.2026
Прошло две недели. Я уже рассказывал, как разговаривал с сотрудниками у сортировки и как понял, что главная ветка — не про приёмку, а про отбор. Но тогда я думал, что понял механику. На этой неделе я. . .
Запись в регистр сведений независимо от заполненности табличной части
Maks 25.08.2026
Реализация из решения ниже выполнена на нетиповом документе с несколькими табличными частями, разработанного в КА2. Задача: Обеспечить запись документа в регистр сведений независимо от. . .
Ноутбук Альфария
kumehtar 24.08.2026
Встретился тут в сети ноутбук Альфария, примарха Альфа-Легиона. Хотя возможно, это ноутбук Омегона, разумеется. Ну как вам?
Мастера простых решений
DevAlt 23.08.2026
В сишарп стэках winforms, да и wpf существует сложная система связывания источниках данных и элементов формы(текстовые поля и метки), опирается все это на технологию событий и мета. . .
Цена ошибки
DevAlt 23.08.2026
Человек я беспокойный и потому заинтересовался OCaml, в чате форсили функторы модулей как суперфичу. Пытаясь отдуплить концепт, наткнулся на тутор с простым примером. А главный принцип обучения от. . .
Сегодня суббота, 22.08.2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины.
zorxor 22.08.2026
Сегодня суббота, 22. 08. 2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru