| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Системное программирование и WinAPI > Завершение потока |
| Автор: En_t_end 5.1.2005, 15:02 | ||
| Надо завершить дополнительный поток... Вот так я делаю :
Программа компилиться, но при тестировании выпадает некоректное юзание памятью Что скажете ? Я использую этот способ(экстр. завершение), потому что данный код исполняется в главном потоке, а не в дополнительном... |
| Автор: chipset 5.1.2005, 15:08 | ||
А проверять не забываем память? Он у тебя не static обьект случаем? |
| Автор: En_t_end 5.1.2005, 15:14 |
| chipset Да... после создания потока, я установил m_bAutoDelete = FALSE, так что в памяти действительно будет висеть Main_pot(вернее его остатки Проблема имхо тут : "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, тут я раз уже своими мыслями делился 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 | ||
Память не выделил для lp_my_ret |
| Автор: 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); //Забыл то самое главное Цикл вообще не правильно организовал Сейчас ещё раз дебагером пройдусь... |
| Автор: 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 статус ложу Добавлено @ 15:36 "лишний раз щелкай кнопкой "Код", так гораздо удобнее читать ;)" Не могу |
| Автор: chipset 5.1.2005, 15:43 | ||||
Память выделяй для lp_my_ret Примерно так: lp_my_ret = new DWORD; Добавлено @ 15:43
Какой браузер? |
| Автор: En_t_end 5.1.2005, 15:48 |
| Какой браузер? Micr. Enternet Expl. Это имхо в поддержке java проблемма... так как любой жабовский скрипт, на моем компе запускаться не хочет, просто ничего не делает Всё заработало Chipset Спасибо... Действительно память не выделил "+" репутация... |
| Автор: chipset 5.1.2005, 15:49 | ||
Надо бы это в фак занести, я на этой фигне дни тратил... |
| Автор: 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 | ||
Я там просто мысли по управлению потока высказывал А слово кстати volatile (при объявлении переменных) тебе что-нибудь говорит? Если нет, то почитай про него что-нибудь в инете. Это очень важно при работе с потоками. Но тут как видно дело было именно в выделении памяти, точнее в ее невыделении А можешь полностью код запостить - интересно посмотреть, что у тебя получлось. Создание потока тоже если можно... Просто в VB с этим проблемы какие-то, а ты тут в принципе API пользуешься, можно попробовать перевести то, что ты написал и посмотреть будет ли работать в VB |
| Автор: En_t_end 6.1.2005, 07:29 |
| cardinal "volatile" "то в локальных переменных этого потока оказывается такая чушь !!!"---Это ты про это ? или про это : ??? ""Но тут как видно дело было именно в выделении памяти, точнее в ее невыделении"" "А можешь полностью код запостить - интересно посмотреть, что у тебя получлось." Пока не могу, до конца ещё не до делал, кстати в "Visual C++ and MFC", про такой способ завершения потока вообще ничего не сказанно, сказанно лишь, что существует TerminateThread(%%%, %%%); и GetExitCodeThread(%%%, %%%);, а дальше сам думай... не хорошо поступили |
| Автор: 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(); //_________ ............................. То всё будет нормально !!! Так как я с памятью ещё не очень научился работать, то по научному обьяснить не могу |
| Автор: En_t_end 6.1.2005, 11:10 |
| cardinal За volatile спасибо, каждый день открываю что-нибудь новое для себя... Насколько понял, это способ оптимизации, так ? |
| Автор: cardinal 6.1.2005, 15:21 | ||
Это способ "защиты" переменной от потери данных |
| Автор: En_t_end 6.1.2005, 15:27 |
| "Это способ "защиты" переменной от потери данных " Ну тыды, я правильно сделал, что не использовал его, так как мне имхо надо было наоборот избавиться от данных, как можно лучше... |
| Автор: chipset 6.1.2005, 15:35 | ||
volatile - указывает оптимизеру что эту переменную нельзя хранить в регистрах поскольку она долговечная.. |
| Автор: cardinal 6.1.2005, 15:35 | ||
Не не совсем так, см. тут: http://doc.mpv.ru/steps/mfc/steps/339.html |
| Автор: cardinal 6.1.2005, 15:46 | ||
Ну и что значит слово "долговечная" |
| Автор: chipset 6.1.2005, 17:04 |
| cardinal Ияжочем.. |