Здравствуйте, Dima2, Вы писали:
D>Ну он вызывал не просто с невалидным хэндлом, а он давал этот невалидный хэндл через указатель неизвестно на что, а ты говориш все нормально, не обращай внимания. Вот за это я собирался тебя побить , ну да ладно выкрутился.
Типа пакт о ненападении?
Предлагаю сделать вывод:
Использование AfxBeginThread с "оставлением" m_bAutoDelete == TRUE и затем ЛЮБЫМ образом pThread->... — заведомо опасная ситуация == misdemeanor
Здравствуйте, Дмитрий Наумов, Вы писали:
ДН>>>Не обращать. <...>
BoundsChecker информирует о вызове системных функций с неправильным handle'ом. Не эстетично, когда в программе warning'и.
А вообще, если создавать тред через ::CreateThread(), но handle, ей возвращаемый, действителен и после завершения TreadProc (например, можно запросить ::GetThreadTimes() с этим handle'ом после завершения), поэтому сдается мне, что тред либо просто не стартует, либо его handle еще не успел оказаться в m_hThread, либо CWinThread его закрывает (смотреть так ли это не хочу принципиально).
Время от времени WaitForSingleObject возвращает WAIT_FAILED, а GetLastError говорит про неправильный хендл. Т.е. похоже, что поток успевает завершиться до WaitForSingleObject. Так как это должно быть написано по правильному?
Здравствуйте, algol, Вы писали:
A>Имеется такой кусок кода: A>
A> CWinThread* pThread = AfxBeginThread(LoadThread, &ld, THREAD_PRIORITY_BELOW_NORMAL);
A> DWORD x = ::WaitForSingleObject(pThread->m_hThread, MAX_WAIT_TIME);
A>
A>Время от времени WaitForSingleObject возвращает WAIT_FAILED, а GetLastError говорит про неправильный хендл. Т.е. похоже, что поток успевает завершиться до WaitForSingleObject. Так как это должно быть написано по правильному?
A>>Время от времени WaitForSingleObject возвращает WAIT_FAILED, а GetLastError говорит про неправильный хендл. Т.е. похоже, что поток успевает завершиться до WaitForSingleObject. Так как это должно быть написано по правильному?
или в ф-ции LoadThread сделай в самом начале Sleep(..)
Один из самых обычных и ведущих к самым большим бедствиям соблазнов есть соблазн словами: "Все так делают".
Лев Толстой
Здравствуйте, algol, Вы писали:
A>Имеется такой кусок кода: A>
A> CWinThread* pThread = AfxBeginThread(LoadThread, &ld, THREAD_PRIORITY_BELOW_NORMAL);
A> DWORD x = ::WaitForSingleObject(pThread->m_hThread, MAX_WAIT_TIME);
A>
A>Время от времени WaitForSingleObject возвращает WAIT_FAILED, а GetLastError говорит про неправильный хендл. Т.е. похоже, что поток успевает завершиться до WaitForSingleObject. Так как это должно быть написано по правильному?
Так я не понял, тебе что мешает что у тебя поток все дела успел сделать, шустрость его мешает?
Здравствуйте, algol, Вы писали:
A>Имеется такой кусок кода: A>
A> CWinThread* pThread = AfxBeginThread(LoadThread, &ld, THREAD_PRIORITY_BELOW_NORMAL);
A> DWORD x = ::WaitForSingleObject(pThread->m_hThread, MAX_WAIT_TIME);
A>
A>Время от времени WaitForSingleObject возвращает WAIT_FAILED, а GetLastError говорит про неправильный хендл.
Может это после AfxBeginThread() неправильный хэндл? Т.е. поток вообще не создался...
Здравствуйте, Dima2, Вы писали:
D>Установить m_bAutoDelete=FALSE или пользоваться ::CreateThread
да, кстати, ведь по умолчанию m_bAutoDelete==TRUE ?
тогда если поток завершился, то объекта pThread у тебя уже нет, программа у тебя должна падать время от времени, или в релизе.
Здравствуйте, Dima2, Вы писали:
D>Здравствуйте, Dima2, Вы писали:
D>>Установить m_bAutoDelete=FALSE или пользоваться ::CreateThread
D>да, кстати, ведь по умолчанию m_bAutoDelete==TRUE ?
точно, точно
D>тогда если поток завершился, то объекта pThread у тебя уже нет, программа у тебя должна падать время от времени, или в релизе.
и в дебаге тоже должна
Один из самых обычных и ведущих к самым большим бедствиям соблазнов есть соблазн словами: "Все так делают".
Лев Толстой
Здравствуйте, Dima2, Вы писали:
D>Здравствуйте, IvEv, Вы писали:
D>>>да, кстати, ведь по умолчанию m_bAutoDelete==TRUE ? IE>>точно, точно
D>Тогда применять CWinThread* после AfxBeginThread нельзя вообще!
В данном случае нельзя...
но если поток запускать с флагом CREATE_SUSPENDED, то можно.
Один из самых обычных и ведущих к самым большим бедствиям соблазнов есть соблазн словами: "Все так делают".
Лев Толстой
Здравствуйте, IvEv, Вы писали:
IE>но если поток запускать с флагом CREATE_SUSPENDED, то можно.
да, если после AfxBeginThread установить флаг m_bAutoDelete==FALSE и не забыть прибить потом объект CWinThread*.
Здравствуйте, Dima2, Вы писали:
D>да, кстати, ведь по умолчанию m_bAutoDelete==TRUE ? D>тогда если поток завершился, то объекта pThread у тебя уже нет, программа у тебя должна падать время от времени, или в релизе.
Нет, объект остается, а вот хендл потока уже недействителен. Так что ничего не падает.
Здравствуйте, algol, Вы писали:
A>Здравствуйте, IvEv, Вы писали:
IE>>или в ф-ции LoadThread сделай в самом начале Sleep(..)
A>Не хотелось бы замедлять выполнение функции.
А запускать поток с CREATE_SUSPENDED тоже не подходит по этой же причине?
Да и еще посмотри что Вшьф2 предлагал
Здравствуйте, Dima2, Вы писали:
D>Здравствуйте, IvEv, Вы писали:
IE>>но если поток запускать с флагом CREATE_SUSPENDED, то можно. D>да, если после AfxBeginThread установить флаг m_bAutoDelete==FALSE и не забыть прибить потом объект CWinThread*.
а не надо забы(и)вать.
IMHO Если после new забываешь delete сделать, то это плохо. Так же нужно относиться и к этой ситуации.
Один из самых обычных и ведущих к самым большим бедствиям соблазнов есть соблазн словами: "Все так делают".
Лев Толстой
Здравствуйте, algol, Вы писали:
A>Здравствуйте, Dima2, Вы писали:
D>>да, кстати, ведь по умолчанию m_bAutoDelete==TRUE ? D>>тогда если поток завершился, то объекта pThread у тебя уже нет, программа у тебя должна падать время от времени, или в релизе.
A>Нет, объект остается, а вот хендл потока уже недействителен. Так что ничего не падает.
т.е. у тебя m_bAutoDelete==FALSE?
Один из самых обычных и ведущих к самым большим бедствиям соблазнов есть соблазн словами: "Все так делают".
Лев Толстой
CREATE_SUSPENDED наверное тоже не подойдет. Точно также процесс может завершиться сразу после ResumeThread(). Предложение Димы2 должно решить проблему, хотя и потребует лишних трех строчек кода.
Здравствуйте, algol, Вы писали:
A>Здравствуйте, Дмитрий Наумов, Вы писали:
ДН>>Так я не понял, тебе что мешает что у тебя поток все дела успел сделать, шустрость его мешает?
A>Меня смущает то, что WaitForSingleObject может быть вызвана с неверным хендлом. Или просто не обращать на это внимания?
Не обращать. У системы есть таблица валидных хэндлов — пусть за этим и следит, а такая ситуация (вызов с уже невалидным хэндлом) все равно может случится, как ты не старайся, поэтому имхо это не криминал. Другое дело был ли создан твой поток и отработал ли он полностью?
Здравствуйте, algol, Вы писали:
A>Здравствуйте, IvEv, Вы писали:
IE>>т.е. у тебя m_bAutoDelete==FALSE?
A>Нет, стоит по умолчанию. Но pThread имеет какое-то значение.
pThread может иметь какое угодно значение — это ведь адрес, но по адресу может уже ничего не быть.
Посмотри в memory, что находится по адресу pThread.
A>Проверить трудно, поскольку под отладчиком все работает нормально.
надолго ли?
Один из самых обычных и ведущих к самым большим бедствиям соблазнов есть соблазн словами: "Все так делают".
Лев Толстой
Здравствуйте, Дмитрий Наумов, Вы писали:
ДН>>>Не обращать. <...> D>>вот я бы тебя побил бы за такие слова, если бы мог ДН>Не понял за что?
Ну как же за что?
В чем причина, что хэндл оказался невалиден? Да вобщем это неважно, валиден он или нет.
Ужас состоит в обращении к pThread->m_hThread, а ты спокойно говориш человеку "да не обращай внимания".
Здравствуйте, Dima2, Вы писали:
D>Здравствуйте, Дмитрий Наумов, Вы писали:
ДН>>>>Не обращать. <...> D>>>вот я бы тебя побил бы за такие слова, если бы мог ДН>>Не понял за что?
D>Ну как же за что? D>В чем причина, что хэндл оказался невалиден? Да вобщем это неважно, валиден он или нет. D>Ужас состоит в обращении к pThread->m_hThread, а ты спокойно говориш человеку "да не обращай внимания".
Эээ батенька, вы перевираете
WaitForSingleObject может быть вызвана с неверным хендлом.
Вот что я сказал и все. К конструкции pThread->m_hThread и возможности ее использования при убитом объекте я никак не ссылаюсь
Здравствуйте, Frostbitten, Вы писали:
F>Здравствуйте, Дмитрий Наумов, Вы писали:
ДН>>>>Не обращать. <...>
F>BoundsChecker информирует о вызове системных функций с неправильным handle'ом. Не эстетично, когда в программе warning'и.
F>А вообще, если создавать тред через ::CreateThread(), но handle, ей возвращаемый, действителен и после завершения TreadProc (например, можно запросить ::GetThreadTimes() с этим handle'ом после завершения), поэтому сдается мне, что тред либо просто не стартует, либо его handle еще не успел оказаться в m_hThread, либо CWinThread его закрывает (смотреть так ли это не хочу принципиально).
Имхо, как я уже говорил, НОРМАЛЬНЫМ (без всяких извращений типа слипов вначале треда) этого не избежать. Например, есть поток, запускающий другие десять и потом ждущий их завершения, причем длительность работы каждого из этих десяти зависит от внешних факторов. Вероятность того что к тому времени как мы все 10 запустим и станем ждать их на WaitForMulti... какой нибудь из них завершится больше нуля. Так что ситуация может случится... Другое дело, что, КАК ВЫ ПРАВИЛЬНО заметили, не стоит использовать зазря, без особой надобности всякие AfxBeginThread
Здравствуйте, Дмитрий Наумов, Вы писали:
ДН>Эээ батенька, вы перевираете
да нет, это ты мастер вырывать фразы из контекста.
WaitForSingleObject может быть вызвана с неверным хендлом
безусловно.
смотри в чем был вопрос A>Меня смущает то, что WaitForSingleObject может быть вызвана с неверным хендлом. Или просто не обращать на это внимания?
Ну он вызывал не просто с невалидным хэндлом, а он давал этот невалидный хэндл через указатель неизвестно на что, а ты говориш все нормально, не обращай внимания. Вот за это я собирался тебя побить , ну да ладно выкрутился.