| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Системное программирование и WinAPI > как корректно остановить поток? |
| Автор: andrew_121 14.5.2009, 14:51 |
| Подскажите, как правильно завершить оного? |
| Автор: GoldFinch 14.5.2009, 15:07 |
| TerminateThread() что значит корректно? все данные в стеке потока убьются, данные в TLS убьются, данные в хипе останутся, данные в секции данных тоже останутся, впрочем обо всем этом написано в msdn напиши откуда ты собрался его завершать. если извне - только TerminateThread() если из самого потока, то либо return в функции потока, либо ExitThread в любом месте алсо, остановить или завершить? |
| Автор: andrew_121 14.5.2009, 15:15 |
Да. Извне. Завершить. |
| Автор: Lazin 14.5.2009, 15:26 | ||||||||
| не стоит использовать CreateThread, вместо этого нужно использовать beginthread beginthreadex, так как они инициализируют структуры данных в TLS, которые необходимы стандартной библиотеке, CreateThread этого не делает... использовать нельзя, после вызова этой ф-ии твое приложение может некорректно работать
то-же не стОит
что-бы корректно завершить поток, нужно сообщить ф-ии потока, что пора завершаться, к примеру
либо можно использовать сообщения windows
|
| Автор: GoldFinch 14.5.2009, 15:41 | ||
| Lazin, если приложение некорректно работает после TerminateThread() это недочет программиста, а не проблемы api функции есть еще такой вариант завершения:
однако это не избавит от "If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread's process could be inconsistent" но такие вобщем-то редкие случаи можно обрабатывать отдельно, флаги выставлять например Добавлено через 2 минуты и 37 секунд еще можно хранить все выделенные потоком ресурсы\память в глобальном объекте, и убивать их после TerminateThread() |
| Автор: mrbrooks 14.5.2009, 15:59 |
| GoldFinch С Lazin'ым согласится старик Рихтер. andrew_121, собственно он же рекомендует использовать beginthreadex вместо CreateThread |
| Автор: Alca 14.5.2009, 16:07 |
| GoldFinch, слушай что профи говорит (Lazin) Добавлено @ 16:08 Можно еще ивенты заюзать. |
| Автор: SenkraD 14.5.2009, 17:26 |
| andrew_121, собстевнно я согласен с Lazin, Alca |
| Автор: azesmcar 14.5.2009, 17:33 |
| andrew_121 забудь про TerminateThread. Поток нужно завершать изнутри, а как сказать своему потоку что он должен завершится смотри пост Lazin. В принципе подойдет любой механизм обмена сообщениями между потоками. а еще exit(0) и TerminateProcess вместо return 0; нахрена вообще придумали нормальное завершение процессов и потоков..всех поубивать |
| Автор: GoldFinch 14.5.2009, 18:19 |
| all вы решаете только те задачи которые придумываете сами? если есть задача убить поток извне - значит ее надо решать, а не говорить "Поток нужно завершать изнутри" задача ТС звучит "Поток нужно завершать ИЗВНЕ" почему именно извне? если вы не можете придумать такую ситуацию, это не говорит что таких ситуаций нет |
| Автор: azesmcar 14.5.2009, 19:09 | ||||
я лично решаю задачи за которые мне платят, а на форуме отвечаю на вопросы - которые поставлены.
замечательно...где в вопросе сказано что поток надо убить? если ты считаешь что правильным завершением потока является убийство - это твое право.
не творческие мы личности..что поделать |
| Автор: jonie 15.5.2009, 10:55 | ||
Завершать потоки убийством крайне плохая идея. У нас есть сервис с ватч догом на работе, один поток котролирует другие (около 150 потоков крутится). Если поток не отвечает своевременно то, его убивают. Итогом этого служит что сервис может работать месяцами, но в определенный момент (после треминайт трейд) начинается коллапс, и все потоки начинают сыпаться.... |
| Автор: Rickert 15.5.2009, 11:08 | ||
А если в потоке стоит получение данных через блокирующий сокет? То бишь аля:
Тогда что предлогается? Засунуть цикл в другой цикл, который будет ловить сообщения для потока? А если собщение придёт(а так скорее всего и будет), в момент когда будет вызвана блок. функция recv() ? CloseHandle - почему не подойдёт? ИМХО: способов много, но надо применять каждому для своей ситуации и нету "правильного" способа, как нет "правильного" синглтона. |
| Автор: mrbrooks 15.5.2009, 11:16 |
| jonie, Rickert - почему вы не сказали что Lazin прав? а это что - завершит поток? |
| Автор: Lazin 15.5.2009, 11:24 |
то нужно использовать неблокирующий сокет |
| Автор: Lazin 15.5.2009, 18:45 | ||
В таких случаях можно вынести часть потоков в один, или несколько дочерних процессов, и обмениваться с ним(и) информацией через какой-нибудь механизм IPC. В случае, если не отвечает - прибить. Разделяй и властвуй |
| Автор: Rickert 15.5.2009, 18:54 |
| Lazin, и всё время крутить цикл, а потом ещё добавить мудрый sleep() ? А должен был? А что - нет? |
| Автор: Lazin 15.5.2009, 18:58 |
combo breaker нет Добавлено через 1 минуту и 36 секунд если коротко, то нет.. вместо этого использовать порты завершения или сообщения windows для организации асинхронной работы |
| Автор: GoldFinch 15.5.2009, 19:00 |
проверял? а если сторонняя библиотека? |
| Автор: Lazin 15.5.2009, 19:00 | ||
| блокирующий сокет разве не может прерывать ожидание по таймауту, я какбэ не в курсе. Добавлено через 3 минуты и 40 секунд
|
| Автор: andrew_121 15.5.2009, 19:07 | ||
А CloseHandle() вызывать после, нужно? |
| Автор: GremlinProg 15.5.2009, 19:09 |
| нужно Добавлено через 1 минуту и 49 секунд если не использовать _beginthread |