Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> как корректно остановить поток? созданый CreateThread() 
V
    Опции темы
andrew_121
Дата 14.5.2009, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 2
Всего: 33



Подскажите, как правильно завершить оного?


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
GoldFinch
Дата 14.5.2009, 15:07 (ссылка)    | (голосов:5) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 2
Всего: 26



TerminateThread()
что значит корректно? все данные в стеке потока убьются, данные в TLS убьются, данные в хипе останутся, данные в секции данных тоже останутся, впрочем обо всем этом написано в msdn

напиши откуда ты собрался его завершать.
если извне - только TerminateThread()
если из самого потока, то либо return в функции потока, либо ExitThread в любом месте

алсо, остановить или завершить?

Это сообщение отредактировал(а) GoldFinch - 14.5.2009, 15:12
PM MAIL ICQ   Вверх
andrew_121
Дата 14.5.2009, 15:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 2
Всего: 33



Цитата(GoldFinch @  14.5.2009,  15:07 Найти цитируемый пост)
если извне - только TerminateThread()

Да. Извне.

Цитата(GoldFinch @  14.5.2009,  15:07 Найти цитируемый пост)
алсо, остановить или завершить?

Завершить.


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
Lazin
Дата 14.5.2009, 15:26 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 8
Всего: 154



не стоит использовать CreateThread, вместо этого нужно использовать beginthread beginthreadex, так как они инициализируют структуры данных в TLS, которые необходимы стандартной библиотеке, CreateThread этого не делает...

Цитата(GoldFinch @  14.5.2009,  15:07 Найти цитируемый пост)
TerminateThread()

использовать нельзя, после вызова этой ф-ии твое приложение может некорректно работать
Цитата(MSDN)

TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread is doing, and you control all of the code that the target thread could possibly be running at the time of the termination. For example, TerminateThread can result in the following problems:


  • If the target thread owns a critical section, the critical section will not be released. 
  • If the target thread is allocating memory from the heap, the heap lock will not be released. 
  • If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread's process could be inconsistent. 
  • If the target thread is manipulating the global state of a shared DLL, the state of the DLL could be destroyed, affecting other users of the DLL. 


Цитата(GoldFinch @  14.5.2009,  15:07 Найти цитируемый пост)
ExitThread 

то-же не стОит
Цитата(MSDN)

ExitThread is the preferred method of exiting a thread in C code. However, in C++ code, the thread is exited before any destructors can be called or any other automatic cleanup can be performed. Therefore, in C++ code, you should return from your thread function.
если конечно ты не пишешь на Си
что-бы корректно завершить поток, нужно сообщить ф-ии потока, что пора завершаться, к примеру
Код

volatile bool run = true;
...
void thread_fn()
{
    while(run)
    {
        ....
    }
}
...
void stop_thread() 
{
    run = false;
    WaitForSingleObject(hThread, INFINITE);//нужно не забывать обрабатывать ошибки
}

либо можно использовать сообщения windows
Код

void thread_fn()
{
    MSG msg;
    while(GetMessage(&msg, 0, 0))
    {
        if (msg.message == WM_QUIT) return;
        ....
    }
}
...
void stop_thread()
{
    PostThreadMessage(hThread, WM_QUIT, 0, 0);//нужно не забывать обрабатывать ошибки
    WaitForSingleObject(hThread, INFINITE);//нужно не забывать обрабатывать ошибки
}

PM MAIL Skype GTalk   Вверх
GoldFinch
Дата 14.5.2009, 15:41 (ссылка)    | (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 2
Всего: 26



Lazin, если приложение некорректно работает после TerminateThread() это недочет программиста, а не проблемы api функции

есть еще такой вариант завершения:

Код

void ThreadFunc(void*) {
    ....
    ThreadCleanup();
   //!!!! сюда управлеине передано не будет
}
void ThreadCleanup() {
   //код освобождения памяти и ресурсов
   ExitThread();
}

//переводим поток на код завершения
CONTEXT ctx;
GetThreadContext(hThr,&ctx);
ctx.eip=&ThreadCleanup;
SetThreadContext(hThr,&ctx);

однако это не избавит от "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()
PM MAIL ICQ   Вверх
Lazin
Дата 14.5.2009, 15:47 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 8
Всего: 154



Цитата(GoldFinch @  14.5.2009,  15:41 Найти цитируемый пост)
если приложение некорректно работает после TerminateThread() это недочет программиста, а не проблемы api функции

это проблемы программиста, который вызывает такие функции
PM MAIL Skype GTalk   Вверх
mrbrooks
Дата 14.5.2009, 15:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: нет
Всего: 306



GoldFinch  С Lazin'ым согласится старик Рихтер.
andrew_121, собственно он же рекомендует использовать beginthreadex вместо CreateThread 
PM MAIL   Вверх
Alca
Дата 14.5.2009, 16:07 (ссылка)    | (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 5
Всего: 50



GoldFinch, слушай что профи говорит (Lazin) smile

Добавлено @ 16:08
Можно еще ивенты заюзать. 

Это сообщение отредактировал(а) Alca - 14.5.2009, 16:09


--------------------
PM WWW ICQ Skype Jabber   Вверх
SenkraD
Дата 14.5.2009, 17:26 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 3.2.2006
Где: Украина::Киев

Репутация: 4
Всего: 23



andrew_121, собстевнно я согласен с Lazin, Alca


--------------------
 Имеющий язык - да не убоится спросить! 
user posted image
PM MAIL ICQ   Вверх
azesmcar
Дата 14.5.2009, 17:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 5
Всего: 211



andrew_121

забудь про TerminateThread. Поток нужно завершать изнутри, а как сказать своему потоку что он должен завершится смотри пост Lazin. В принципе подойдет любой механизм обмена сообщениями между потоками.
Цитата(GoldFinch @  14.5.2009,  15:07 Найти цитируемый пост)
TerminateThread()

а еще
exit(0) и TerminateProcess вместо return 0;
нахрена вообще придумали нормальное завершение процессов и потоков..всех поубивать
PM   Вверх
GoldFinch
Дата 14.5.2009, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 2
Всего: 26



all
вы решаете только те задачи которые придумываете сами?
если есть задача убить поток извне - значит ее надо решать, а не говорить "Поток нужно завершать изнутри"
задача ТС звучит "Поток нужно завершать ИЗВНЕ"
почему именно извне? если вы не можете придумать такую ситуацию, это не говорит что таких ситуаций нет
PM MAIL ICQ   Вверх
azesmcar
Дата 14.5.2009, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 5
Всего: 211



Цитата(GoldFinch @  14.5.2009,  18:19 Найти цитируемый пост)
вы решаете только те задачи которые придумываете сами?

я лично решаю задачи за которые мне платят, а на форуме отвечаю на вопросы - которые поставлены.

Цитата(GoldFinch @  14.5.2009,  18:19 Найти цитируемый пост)
если есть задача убить поток извне - значит ее надо решать, а не говорить "Поток нужно завершать изнутри"

замечательно...где в вопросе сказано что поток надо убить?

Цитата(andrew_121 @  14.5.2009,  14:51 Найти цитируемый пост)
Подскажите, как правильно завершить оного? 

если ты считаешь что правильным завершением потока является убийство - это твое право.


Цитата(GoldFinch @  14.5.2009,  18:19 Найти цитируемый пост)
почему именно извне? если вы не можете придумать такую ситуацию, это не говорит что таких ситуаций нет 

не творческие мы личности..что поделать
PM   Вверх
jonie
Дата 15.5.2009, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 7
Всего: 118



Цитата


если есть задача убить поток извне - значит ее надо решать, а не говорить "Поток нужно завершать изнутри"
задача ТС звучит "Поток нужно завершать ИЗВНЕ"
что первее курица или яйцо ?)

Завершать потоки убийством крайне плохая идея. У нас есть сервис с ватч догом на работе, один поток котролирует другие (около 150 потоков крутится). Если поток не отвечает своевременно то, его убивают. Итогом этого служит что сервис может работать месяцами, но в определенный момент (после треминайт трейд) начинается коллапс, и все потоки начинают сыпаться.... 



--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Rickert
Дата 15.5.2009, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: нет
Всего: 52



А если в потоке стоит получение данных через блокирующий сокет? То бишь аля:
Код
while(r != (-1)) {r = recv(...);...}

Тогда что предлогается? Засунуть цикл в другой цикл, который будет ловить сообщения для потока? А если собщение придёт(а так скорее всего и будет), в момент когда будет вызвана блок. функция recv() ?
CloseHandle - почему не подойдёт?
ИМХО: способов много, но надо применять каждому для своей ситуации и нету "правильного" способа, как нет "правильного" синглтона.


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
mrbrooks
Дата 15.5.2009, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: нет
Всего: 306



 smile 
jonie, Rickert - почему вы не сказали что Lazin прав?

Цитата(Rickert @  15.5.2009,  11:08 Найти цитируемый пост)
CloseHandle - почему не подойдёт?

а это что - завершит поток?  smile 


PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0648 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.