Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Завершение потока


Автор: En_t_end 5.1.2005, 15:02
Надо завершить дополнительный поток...
Вот так я делаю :
Код



               LPDWORD lp_my_ret;
TerminateThread(Main_pot->m_hThread, 0);
GetExitCodeThread(Main_pot->m_hThread, lp_my_ret);
while(*lp_my_ret == STILL_ACTIVE)
{
        Sleep(10);
}
GlobalFree(Main_pot);

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

Автор: chipset 5.1.2005, 15:08
Цитата(En_t_end @ 5.1.2005, 04:02)
GlobalFree(Main_pot);

А проверять не забываем память? smile
Он у тебя не static обьект случаем?

Автор: En_t_end 5.1.2005, 15:14
chipset
Да... после создания потока, я установил m_bAutoDelete = FALSE, так что в памяти действительно будет висеть Main_pot(вернее его остатки smile), и вообще я методом тыка комментил GlobalFree(), всё равно такая же лажа smile
Проблема имхо тут :
"GetExitCodeThread(Main_pot->m_hThread, lp_my_ret);
while(*lp_my_ret == STILL_ACTIVE)"
Добавлено @ 15:18
CWinThread *Main_pot;

Автор: chipset 5.1.2005, 15:19
Пройдись дебаггером и посмотри где происходит выброс памяти.
Желательно ещё использовать клавишу F11 (в VC7.1).

Автор: cardinal 5.1.2005, 15:22
En_t_end, тут я раз уже своими мыслями делился smile
http://forum.vingrad.ru/index.php?showtopic=36975&view=findpost&p=276689

Автор: En_t_end 5.1.2005, 15:26
Прошёлся по-этапно дебаггером, ошибка здесь :
*lp_my_ret == STILL_ACTIVE
Почему сравнение не правильно ?
Добавлено @ 15:29
cardinal
А где именно ты говорил про аннологичную ситуацию ?
Тут проблемма имхо в другом...

Автор: chipset 5.1.2005, 15:31
Цитата(En_t_end @ 5.1.2005, 04:26)
*lp_my_ret == STILL_ACTIVE

Память не выделил для lp_my_ret smile

Автор: En_t_end 5.1.2005, 15:32
LPDWORD lp_my_ret;
TerminateThread(Main_pot->m_hThread, 0);
GetExitCodeThread(Main_pot->m_hThread, lp_my_ret);
while(*lp_my_ret == STILL_ACTIVE)
{
Sleep(10);
GetExitCodeThread(Main_pot->m_hThread, lp_my_ret);
}
GlobalFree(Main_pot);
//Забыл то самое главное smile : GetExitCodeThread(Main_pot->m_hThread, lp_my_ret);
Цикл вообще не правильно организовал smile
Сейчас ещё раз дебагером пройдусь...

Автор: chipset 5.1.2005, 15:33
En_t_end, лишний раз щелкай кнопкой "Код", так гораздо удобнее читать ;)

Автор: En_t_end 5.1.2005, 15:35
Ага теперь материться на GetExitCodeThread(Main_pot->m_hThread, lp_my_ret), видно не правильно я в lp_my_ret статус ложу smile

Добавлено @ 15:36
"лишний раз щелкай кнопкой "Код", так гораздо удобнее читать ;)"
Не могу smile... не работает, причём не только на этом форуме...

Автор: chipset 5.1.2005, 15:43
Цитата(En_t_end @ 5.1.2005, 04:35)
Ага теперь материться на GetExitCodeThread(Main_pot->m_hThread, lp_my_ret), видно не правильно я в lp_my_ret статус ложу smile

Память выделяй для lp_my_ret
Примерно так: lp_my_ret = new DWORD;
Добавлено @ 15:43
Цитата(En_t_end @ 5.1.2005, 04:35)
Не могу smile... не работает, причём не только на этом форуме...

Какой браузер?

Автор: En_t_end 5.1.2005, 15:48
Какой браузер?
Micr. Enternet Expl.
Это имхо в поддержке java проблемма... так как любой жабовский скрипт, на моем компе запускаться не хочет, просто ничего не делает smile
Всё заработало
Chipset Спасибо...
Действительно память не выделил smile
"+" репутация...

Автор: chipset 5.1.2005, 15:49
Цитата(En_t_end @ 5.1.2005, 04:48)
Действительно память не выделил smile

Надо бы это в фак занести, я на этой фигне дни тратил...

Автор: chipset 5.1.2005, 16:19
Модератор: перенесено из Visual C++/MFC/WTL в Системное программирование

Автор: En_t_end 5.1.2005, 16:31
ОФФТОП почему из Visual C++/MFC/WTL в Системное программирование ???
Тут теперь ещё странность одна...
Если допустим поток завершился во время спячки(Sleep(-n-)), то, если я захочу создать ещё раз этот поток, то в локальных переменных этого потока оказывается такая чушь !!!
Интересно из-за чего это ?

Автор: cardinal 5.1.2005, 17:27
Цитата(En_t_end @ 5.1.2005, 13:26)
А где именно ты говорил про аннологичную ситуацию ?

Я там просто мысли по управлению потока высказывал smile

А слово кстати volatile (при объявлении переменных) тебе что-нибудь говорит? Если нет, то почитай про него что-нибудь в инете. Это очень важно при работе с потоками.

Но тут как видно дело было именно в выделении памяти, точнее в ее невыделении smile

А можешь полностью код запостить - интересно посмотреть, что у тебя получлось. Создание потока тоже если можно...
Просто в VB с этим проблемы какие-то, а ты тут в принципе API пользуешься, можно попробовать перевести то, что ты написал и посмотреть будет ли работать в VB smile

Автор: En_t_end 6.1.2005, 07:29
cardinal
"volatile"
"то в локальных переменных этого потока оказывается такая чушь !!!"---Это ты про это ? или про это : ???
""Но тут как видно дело было именно в выделении памяти, точнее в ее невыделении""

"А можешь полностью код запостить - интересно посмотреть, что у тебя получлось."
Пока не могу, до конца ещё не до делал, кстати в "Visual C++ and MFC", про такой способ завершения потока вообще ничего не сказанно, сказанно лишь, что существует TerminateThread(%%%, %%%); и GetExitCodeThread(%%%, %%%);, а дальше сам думай... не хорошо поступили smile

Автор: En_t_end 6.1.2005, 08:46
Всё ура!!!... с переменными разобрался... кстати тоже мучился около недели...
Если кому-то интересно :
ПОТОК -_- Вообще-то проблема была в местах использования этих переменных...
Я записывал, допустим из файла в цикле значения в переменные, вот так я делал : (кому не трудно, плиз, сделайте "код" на этих записях !)

///////Глобальное...///////
ifstream config;
ifstream config_2;
ofstream log_my;
CWinThread *Main_pot;
///////////////////////////////
UINT Potoc(LPVOID pParam)
{
char N[37];
int P_I = 0;
for(;;)
{
P_I = 0;
config.open("config.C");
config_2.open("config_2.C");
log_my.open("last_Status.C");
config >> N;
config_2 >> P_I;
log_my << N << endl << P_I << endl;
log_my.flush();

GlobalFree(N); // Некорректное исполнение
config_2.close(); // ______________________
config.close(); // _________________
log_my.close(); //_________
Sleep(6000); //_____
}
}
...............................................

void CProg::OnStart()
{
.................................
Main_pot = AfxBeginThread((AFX_THREADPROC)Potoc, (LPVOID)&Status, THREAD_PRIORITY_NORMAL, 0, 0, NULL);
Main_pot->m_bAutoDelete = FALSE;
}
................................
void CProg::OnStop()
{
................................................
LPDWORD lp_my_ret;
lp_my_ret = new DWORD;
TerminateThread(Main_pot->m_hThread, 0);
GetExitCodeThread(Main_pot->m_hThread, lp_my_ret);
while(*lp_my_ret == STILL_ACTIVE)
{
Sleep(10);
GetExitCodeThread(Main_pot->m_hThread, lp_my_ret);
}
config_2.close();
config.close();
log_my.close();
GlobalFree(Main_pot);
GlobalFree(lp_my_ret);
..................
}




Вот если успевать нажать на СТОП во время спячки Main_pot, то после повторного запуска, в переменных окажется мега-чушь, а если заменить вот эти строчки :
.............................
GlobalFree(N); // Некорректное исполнение
config_2.close(); // ______________________
config.close(); // _________________
log_my.close(); //_________
Sleep(6000); //_____
.............................

на эти :
.............................
Sleep(6000); //_____
GlobalFree(N); // Корректное исполнение
config_2.close(); // ______________________
config.close(); // _________________
log_my.close(); //_________
.............................
То всё будет нормально !!!
Так как я с памятью ещё не очень научился работать, то по научному обьяснить не могу smile

Автор: En_t_end 6.1.2005, 11:10
cardinal
За volatile спасибо, каждый день открываю что-нибудь новое для себя...
Насколько понял, это способ оптимизации, так ?

Автор: cardinal 6.1.2005, 15:21
Цитата(En_t_end @ 6.1.2005, 09:10)
Насколько понял, это способ оптимизации, так ?

Это способ "защиты" переменной от потери данных smile

Автор: En_t_end 6.1.2005, 15:27
"Это способ "защиты" переменной от потери данных "
Ну тыды, я правильно сделал, что не использовал его, так как мне имхо надо было наоборот избавиться от данных, как можно лучше...

Автор: chipset 6.1.2005, 15:35
Цитата(En_t_end @ 6.1.2005, 00:10)
Насколько понял, это способ оптимизации, так ?

volatile - указывает оптимизеру что эту переменную нельзя хранить в регистрах поскольку она долговечная..

Автор: cardinal 6.1.2005, 15:35
Цитата(En_t_end @ 6.1.2005, 13:27)
Ну тыды, я правильно сделал, что не использовал его, так как мне имхо надо было наоборот избавиться от данных, как можно лучше...

Не не совсем так, см. тут:
http://doc.mpv.ru/steps/mfc/steps/339.html

Автор: cardinal 6.1.2005, 15:46
Цитата(chipset @ 6.1.2005, 13:35)
volatile - указывает оптимизеру что эту переменную нельзя хранить в регистрах поскольку она долговечная..

Ну и что значит слово "долговечная" smile Просто потому, что значение ее тот же поток изменит и ты потом долго будешь думать почему же у тебя error. А так она точно сидит не в регистре и соответственно никто ей ничего не сделает (кроме тебя самого smile).

Автор: chipset 6.1.2005, 17:04
cardinal
Ияжочем.. smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)