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

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

07.10.2023, 12:10. Показов 4376. Ответов 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,686
Записей в блоге: 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,686
Записей в блоге: 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
1074 / 514 / 41
Регистрация: 05.05.2022
Сообщений: 3,658
09.10.2023, 10:22
Кстати, а кто мешает в каждом из потоков по завершении проверять весь пул потоков, и если поток обнаружит, что он последний, то сделает еще какую-то работу?
0
 Аватар для krapotkin
6854 / 4680 / 1465
Регистрация: 14.04.2014
Сообщений: 20,686
Записей в блоге: 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,686
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru