Нужно ли явно останавливать все потоки перед выходом из приложения Win32? - PullRequest
10 голосов
/ 04 февраля 2010

У меня есть родное приложение VC ++ для Win32, которое при вводе WinMain() запускает отдельный поток, затем выполняет некоторую полезную работу во время работы другого потока, а затем просто завершает работу WinMain() - другой поток явно не останавливается.*

В этом блоге говорится, что в этом случае приложение .NET не завершит свою работу, так как другой поток все еще работает.Относится ли это к родным приложениям Win32?

Нужно ли останавливать все потоки перед выходом?

Ответы [ 5 ]

8 голосов
3 голосов
/ 04 февраля 2010

Суть этого: Для завершения собственного процесса Win32 должно быть выполнено одно из двух условий:

  • Кто-то вызывает ExitProcess или TerminateProcess.
  • Все потоки выходят (возвращаясь из их ThreadProc (включая WinMainEntryPoint, который является первым потоком, созданным окнами)), закрываются (путем вызова ExitThread) или завершаются (кто-то вызывает TerminateThread).

(Первое условие фактически совпадает со вторым: ExitProcess и TerminateProcess, как часть их очистки, оба вызывают TerminateThread для каждого потока в процессе).

Время выполнения c накладывает различные условия: чтобы завершить работу приложения C / C ++, вы должны либо:

  • возврат из основного (или WinMain).
  • вызов выхода ()

Вызов exit () или возврат из main () приводит к тому, что c-runtime вызывает ExitProcess (). Именно так выходят приложения c & c ++ без очистки их потоков. Я лично считаю, что это плохо.

Тем не менее, нетривиальные процессы Win32 никогда не могут завершиться, потому что многие совершенно, в противном случае разумные, подсистемы Win32 создают рабочие потоки. winsock, ole и т. д. И не предоставляют никакого способа самопроизвольно закрыть эти потоки.

2 голосов
/ 04 февраля 2010

Нет, когда WinMain вернется, процесс будет прерван, и это означает, что все потоки, порожденные процессом, должны быть прерваны, хотя они могут не закрываться изящно.основной поток завершается во время работы других потоков, в результате чего приложение все еще работает .Если вы вызываете ExitThread (не exit или ExitProcess) в WinMain, и есть запущенные потоки (в конечном итоге созданные основным потоком), то вы можете наблюдать это поведение.Тем не менее, просто возврат в WinMain вызовет ExitProcess, и это означает, что все потоки должны быть прерваны.

Исправьте меня, если это не так.

0 голосов
/ 06 февраля 2010

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

после установки флага ваш основной поток может некоторое время вызывать :: WaitForSingleObject () или :: WaitForMultipleObjects () (скажем, три секунды), если поток (потоки) не возвращается, просто убейте их с помощью :: TerminateThread ().

0 голосов
/ 04 февраля 2010

короткий ответ: да

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...