Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.94/63: Рейтинг темы: голосов - 63, средняя оценка - 4.94
Техник
 Аватар для DenProx
318 / 176 / 27
Регистрация: 09.10.2009
Сообщений: 3,109

Многопоточные приложения (остановить поток)

21.06.2012, 14:57. Показов 13230. Ответов 92
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток. У меня такая проблемка, программа включается в себя 2 дополнительных потока, которые создаются при старте проги:

C++
1
2
3
4
........
        hThread = CreateThread(NULL,0,&ServiceThread,0,0,&idThread);
        hThread_shim = CreateThread(NULL,0,&ShimProc,0,0,&idThread_shim);
........
все работает. Но при попытке закрыть программу, она зависает мертвым грузом ...

на событии OnClose стоит такой код:

C++
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
try
        {
                EnterCriticalSection(section_harvest);
                StopThread_harvest = true;
        }
        __finally
        {
                LeaveCriticalSection(section_harvest);
        }
 
        try
        {
                EnterCriticalSection(section);
                stop_shim = true;
        }
        __finally
        {
                LeaveCriticalSection(section);
        }
        //CloseHandle(hThread);
 
        DWORD exitCode;
        do
        {
                GetExitCodeThread(hThread,&exitCode);
        }
        while(exitCode == STILL_ACTIVE);
 
     .................
 
        WaitForSingleObject(Handle,200);

почему может зависать? и как корректно завершить выполнение потоков и вообще программы с несколькими потоками?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.06.2012, 14:57
Ответы с готовыми решениями:

Многопоточные приложения
Создайте приложение, которое в фоновом режиме проверяет правильно введенные числа. На главной форме разместите два многострочных редактора....

Многопоточные приложения
Доброго времени суток всем! Кто-нибудь может дать дельные ссылки на информацию/исходник по многопоточным приложениям?

Многопоточные приложения
Помогите пожалуйста написать такую программу Создать многопоточное приложение, в котором поток родитель создает файл и создает три...

92
 Аватар для ExeiLj
13 / 13 / 3
Регистрация: 02.08.2012
Сообщений: 128
01.09.2012, 21:09
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Avazart Посмотреть сообщение
Ну логично что и MyThr->WaitFor(); тоже нужно убрать...
Но ведь мне нужно как-то дождаться, пока поток завершиться! Без WaitFor, как я дождусь?
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.09.2012, 21:41
Цитата Сообщение от ExeiLj Посмотреть сообщение
не нужно как-то дождаться, пока поток завершиться!
Зачем ?

Добавлено через 17 минут
Нашел деструктор

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
destructor TThread.Destroy;
begin
  if (FThreadID <> 0) and not FFinished and not FExternalThread then
  begin
    Terminate;
    if FCreateSuspended then
      Resume;
    WaitFor;
  end;
  RemoveQueuedEvents(Self, nil);
{$IFDEF MSWINDOWS}
  if (FHandle <> 0) and not FExternalThread then CloseHandle(FHandle);
{$ENDIF}
{$IFDEF LINUX}
  // This final check is to ensure that even if the thread was never waited on
  // its resources will be freed.
  if (FThreadID <> 0) and not FExternalThread then pthread_detach(FThreadID);
  sem_destroy(FCreateSuspendedSem);
{$ENDIF}
  inherited Destroy;
  FFatalException.Free;
  RemoveThread;
end;
Добавлено через 12 минут
Строчка 5 Terminate -что говорит что деструктор устанавливает флаг
Не могу только понять что делают строчки
Delphi
1
2
RemoveQueuedEvents(Self, nil);
RemoveThread;
0
 Аватар для ExeiLj
13 / 13 / 3
Регистрация: 02.08.2012
Сообщений: 128
01.09.2012, 21:55
Цитата Сообщение от Avazart Посмотреть сообщение
Зачем ?
Затем, что если не дожидаться, программа сразу закроется, а поток не успеет дойти до момента, когда сам завершится и следовательно не освободит память!
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.09.2012, 21:56
Об этом должен позаботиться сам поток. Зачем тогда вообще свойство FrreOnTerminate ?

По крайней мере у Архангелького об этом ничего не сказано.
0
 Аватар для ExeiLj
13 / 13 / 3
Регистрация: 02.08.2012
Сообщений: 128
01.09.2012, 22:03
Цитата Сообщение от Avazart Посмотреть сообщение
Об этом должен позаботиться сам поток. Зачем тогда вообще свойство FrreOnTerminate ?
Затем, чтобы освободить память, когда поток закончится. А если мы завершим процесс до того как поток закроется, то и FreeOnTerminate не сработает, поэтому надо дожидаться его!
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.09.2012, 22:18
Тем более насколько я понимаю код Delphi исходников об этом заботиться деструктор как я предпологал
Delphi
1
2
3
Terminate;
//...
WaitFor;
Поэтому достаточно делать delete при FrreOnTerminate= false; в OnClose формы
0
 Аватар для ExeiLj
13 / 13 / 3
Регистрация: 02.08.2012
Сообщений: 128
01.09.2012, 22:18
Цитата Сообщение от Avazart Посмотреть сообщение
Тем более насколько я понимаю код Delphi исхоников об этом заботится деструктор как я предпологал
Delphi
1
2
3
Terminate;
//...
WaitFor;
Это работает только пока запущен процесс.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.09.2012, 22:19
Какой процесс?
0
 Аватар для ExeiLj
13 / 13 / 3
Регистрация: 02.08.2012
Сообщений: 128
01.09.2012, 22:24
Цитата Сообщение от Avazart Посмотреть сообщение
Какой процесс?
Основной процесс, то бишь приложение, программа.
Пока программа работает, потоки в ней, которые заканчивают делать свою работу автоматически освобождаются деструктором. Но если мы закроем программу, то и деструктор посути закроем, ведь он в коде этой программы, а значит нечему будет уничтожить поток.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.09.2012, 22:38
Основной поток или процесс ?- не путайте меня...

Если процесс (т.е программа) закончен, то уже поздно Операционная система почистила все за вас ( хотя конечно не факт )


Если мы закроем прорамму то в OnClose нужно писать Thread1->Terminate() что вызовет что-то что выполнит корректное удаление.

(возможно это что-то деструктор, но не факт )

Добавлено через 7 минут
Хотя это только предположение, нужно смотреть исходники...
0
 Аватар для ExeiLj
13 / 13 / 3
Регистрация: 02.08.2012
Сообщений: 128
01.09.2012, 22:44
Цитата Сообщение от Avazart Посмотреть сообщение
Основной поток или процесс ?- не путайте меня...
процесс, хотя есть разница? при завершении основного потока завершается и процесс или наоборот.

Цитата Сообщение от Avazart Посмотреть сообщение
Если процесс (т.е программа) закончен, то уже поздно Операционная система почистила все за вас ( хотя конечно не факт )
Вот именно, что ОС ничего за вас чистить не будет. Если программа завершена, а потоки вы не очистили, то они останутся в памяти и ОС ничего не будет делать с этим.

Цитата Сообщение от Avazart Посмотреть сообщение
Если мы закроем прорамму то в OnClose нужно писать Thread1->Terminate() что вызовет что-то что выполнит корректное удаление.
Вот именно, что это ничего не вызывает, разве что вы сами в потоке не создали кучу проверок if (Terminated) ...
И даже после вызова Terminate() надо ждать, пока поток закроется, если не ждать, то он не закроется!
Поэтому везде используют WaitFor или WaitForSingleObject (последнее у меня почему-то криво работает в OnClose...)
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.09.2012, 23:03
Цитата Сообщение от ExeiLj Посмотреть сообщение
процесс, хотя есть разница? при завершении основного потока завершается и процесс или наоборот.
Цитата Сообщение от ExeiLj Посмотреть сообщение
Вот именно, что ОС ничего за вас чистить не будет. Если программа завершена, а потоки вы не очистили, то они останутся в памяти и ОС ничего не будет делать с этим.
Ну думаю вам стоит почитать что нибудь об этом...спорить тут безполезно если вы не отличаете поток от процесса.


Поэтому везде используют WaitFor
Где используют ?

Добавлено через 13 минут
Цитата Сообщение от ExeiLj Посмотреть сообщение
разве что вы сами в потоке не создали кучу проверок if (Terminated)
А без этого не как "мягкого" завершения не добиться.
0
 Аватар для ExeiLj
13 / 13 / 3
Регистрация: 02.08.2012
Сообщений: 128
01.09.2012, 23:58
Цитата Сообщение от Avazart Посмотреть сообщение
Ну думаю вам стоит почитать что нибудь об этом...спорить тут безполезно если вы не отличаете поток от процесса.
Отличаю. Процесс ничего не делает, это всего лишь обертка, все действия выполняются потоком. Поэтому в процессе всегда имеется, как минимум, один поток - основной поток. И завершение процесса равносильно завершению основного потока.

Цитата Сообщение от Avazart Посмотреть сообщение
Где используют ?
В примерах.

Цитата Сообщение от Avazart Посмотреть сообщение
А без этого не как "мягкого" завершения не добиться.
Мягкое завершение означает ожидание, пока поток сам завершит себя.
Если мы резко закроем процесс (без ожидания), то поток не успеет сам завершить себя. И поток точно не будет завершать себя, уже после закрытия процесса.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
02.09.2012, 00:07
Процесс ничего не делает, это всего лишь обертка, все действия выполняются потоком.
Операционная система выделяет память под процесс, а не под поток...

Добавлено через 28 секунд
Цитата Сообщение от ExeiLj Посмотреть сообщение
В примерах.
Можно ссылки ?

Добавлено через 3 минуты
И завершение процесса равносильно завершению основного потока.
Равносильно завершению всех потоков...

Добавлено через 2 минуты
Цитата Сообщение от ExeiLj Посмотреть сообщение
Мягкое завершение означает ожидание, пока поток сам завершит себя.
Может и так зависит от программы...
0
 Аватар для ExeiLj
13 / 13 / 3
Регистрация: 02.08.2012
Сообщений: 128
02.09.2012, 00:22
Цитата Сообщение от Avazart Посмотреть сообщение
Операционная система выделяет память под процесс, а не под поток...
Да, так и есть. И что с того? Это ничего не меняет. Память выделяется процессу, и эту память используют все потоки в контексте данного процесса. Но если какой-то поток не будет завершен, то память не будет освобождена, даже если процесс будет закрыт. А значит она по сути будет заблокирована и тупо съедена вникуда.

Цитата Сообщение от Avazart Посмотреть сообщение
Можно ссылки ?
Цитата Сообщение от ExeiLj Посмотреть сообщение
Цитата Сообщение от Avazart Посмотреть сообщение
Равносильно завершению всех потоков...
Да нет же! В том-то и дело: можно завершить процесс и не завершить потоки! Иначе бы никто не парился и не заботился о завершении потоков.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
02.09.2012, 00:55
Цитата Сообщение от ExeiLj Посмотреть сообщение
Но если какой-то поток не будет завершен, то память не будет освобождена, даже если процесс будет закрыт. А значит она по сути будет заблокирована и тупо съедена вникуда.
Да нет, винда освободит всю память процесса после его закрытия...

Добавлено через 2 минуты
Цитата Сообщение от ExeiLj Посмотреть сообщение
Ну так это форум...тем более, что пример для FreeOnTerminate= false; а если ориентироваться на исходники то код там избыточный

Добавлено через 21 минуту
Ага понял...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//---------------------------------------------------------------------------
__fastcall TMyThread::TMyThread(bool CreateSuspended)
    : TThread(CreateSuspended)
{
FreeOnTerminate= false;
}
//---------------------------------------------------------------------------
void __fastcall TMyThread::Execute()
{
using namespace std;
 
ofstream ofs;
ofs.open("log.txt");
if(ofs) ofs<<"start"<<endl;
 
Sleep(60000);
 
if(ofs) ofs<<"exit"<<endl;
}
//---------------------------------------------------------------------------
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
TMyThread* Thread1;
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Thread1 = new TMyThread(false);
 
Sleep(5000);
Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
delete Thread1;
}
//---------------------------------------------------------------------------
При нажатии на кнопку код отрабатывает как надо: ждет минуту а потом только закрывается окно, а в файле видим обе записи:
start
exit
Но если не вызывать деструктор или использовать FreeOnTerminate= true; в FormClose вписать (вместо delete Thread1)
Thread1->Terminate(); то программа закроется быстрее и в файле увидим только строку start
0
 Аватар для ExeiLj
13 / 13 / 3
Регистрация: 02.08.2012
Сообщений: 128
02.09.2012, 02:15
Цитата Сообщение от Avazart Посмотреть сообщение
Да нет, винда освободит всю память процесса после его закрытия...
Так значит это
Цитата Сообщение от ExeiLj Посмотреть сообщение
То есть при закрытии приложения(формы) необходимо завершать все потоки? разве они сами не закроются?
Цитата Сообщение от DenProx Посмотреть сообщение
ExeiLj, нет, если их не завершить они так и будут сидеть в памяти
неправда?

Цитата Сообщение от Avazart Посмотреть сообщение
Но если не вызывать деструктор или использовать FreeOnTerminate= true; в FormClose вписать (вместо delete Thread1)
Thread1->Terminate(); то программа закроется быстрее и в файле увидим только строку start
Так значит если закрыть прогу во время выполнения потока при FreeOnTerminate= true; таки будет утечка памяти?
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
02.09.2012, 02:26
Так значит если закрыть прогу во время выполнения потока при FreeOnTerminate= true; таки будет утечка памяти?
Думаю будет авариное завершение потока... наверное аналогичное TerminateThread()

таки будет утечка памяти?
Возможно будет не закрыты какие то хендлы, индитификаторы итп...

Вообщем не нормально это будет ...

Цитата Сообщение от ExeiLj
неправда?
Джеффри РИХТЕР "Windows для профессионалов"
Глава 6 Базовые сведения о потоках

http://wm-help.net/books-onlin... 64-25.html


Поток можно завершить четырьмя способами:

-функция потока возвращает управление (рекомендуемый способ),

-поток самоуничтожяется вызовом функции ExitThread (нежелательный способ);

-один из потоков данного или стороннего процесса вызывает функцию Termi nateThread (нежелательный способ);

-завершается процесс, содержащий данный поток (тоже нежелательно).

Если завершается процесс

Функции ExitProcess и TerminateProcess, рассмотренные в главе 4, тоже завершают потоки. Единственное отличие в том, что они прекращают выполнение всех потоков, принадлежавших завершенному процессу При этом гарантируется высвобождение любых выделенных процессу ресурсов, в том числе стеков потоков Однако эти две функции уничтожают потоки принудительно — так, будто для каждого из них вызы вается функция TerminateThread. А это означает, что очистка проводится некоррект но, деструкторы С++-объектов не вызываются, данные на диск не сбрасываются и т д
1
 Аватар для ExeiLj
13 / 13 / 3
Регистрация: 02.08.2012
Сообщений: 128
02.09.2012, 02:34
Ясно, значит переживать за завершение потока в любом случае не стоит.
Но все же лучше завершать корректно

И для FreeOnTerminate=true таки требуется ожидание завершения потока. Только вот WaitFor не сгодится, а WaitForSingleObject в OnClose у меня работает не правильно...
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
02.09.2012, 02:45
1. Не использовать FreeOnTerminate= true;
2. В FormCloseQuery не давать закрыть форму пока Fineshed не станет true;
3 ...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.09.2012, 02:45

Многопоточные консольные приложения
подскажите сайт\книжку где почитать (обязательно с примерами) про многопоточные приложения, и только с консольными примерами. в этой...

Как проще проектировать многопоточные или асинхронные приложения?
Доброе утро! Подскажите, пожалуйста, какая есть документация на эту тему?

Как писать многопоточные приложения, использующие разделяемые ресурсы
Здравствуйте. Возможно, у кого-либо найдется время, чтобы показать, как писать многопоточные приложения, использующие разделяемые...

Остановить поток
Есть 3 потока 1-главный он отвечает за выполнение 2 и 3 потока нужно: 1 поток сотановился и запустил 2 поток, 2 поток выполнил свое...

Остановить поток
Помогите пожалуйста создать кнопку, нажав на которую можно было бы остановить поток.


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

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Новые блоги и статьи
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
День 5 из 28: Codex подсказывает следующий запрос
and_y87 12.10.2026
9 октября 2026 года OpenAI запустила бету Composer predictions — подсказок следующего сообщения в текущем диалоге Codex. Это помощь с формулировкой запроса, а не автоматическое продолжение задачи. . . .
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru