Почему этот код теряет дескрипторы в бета-версии Windows 7? - PullRequest
4 голосов
/ 16 февраля 2009

Я ищу случайные сбои в старом приложении c ++. Используя sysinternals Process Explorer, я заметил, что приложение теряет дескрипторы, и извлек точную ситуацию, когда программа теряет дескрипторы к очень короткому куску кода.

DWORD WINAPI MyTestThread( void*  PThread)
{
 _endthreadex(0);
 return 0;
}

int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR  PParameter, int)
{
 for (int i=0;i<10000;i++)
 {
   unsigned int threadID;
   HANDLE hThread= (HANDLE)_beginthreadex( (void*)NULL, (unsigned int)32768, (unsigned int (__stdcall *)(void *))MyTestThread, (void*)NULL, (unsigned int)0, &threadID);
   WaitForSingleObject((HANDLE)hThread, 1000);
   CloseHandle((HANDLE)hThread);
 }
 return 0;
}

Моя проблема: я не могу понять, что не так с этим кодом. Он теряет ровно 5 дескрипторов на каждой итерации, но для меня это выглядит нормально.
Забавная вещь: кажется, не потерять ручки на Windows Vista, но я был бы очень удивлен, если это будет ошибка в Windows 7.

[Обновить] Я попытался использовать _beginthread / _endthread и CreateThread / ExitThread вместо этого, эти два тоже теряют 5 дескрипторов, как _beginthreadex.

[2-е обновление] код работает должным образом. Все возвращаемые значения хороши. Это «просто» потеря ручек, как будто завтрашнего дня нет.

[3-е обновление] Большая новая информация Код теряет дескрипторы, только если скомпилирован с / clr! И еще, если я вызову GC :: Collect () на каждой итерации, дескрипторы будут исправлены!
Итак, как мне найти, какие clr-объекты там собираются?

Ответы [ 4 ]

2 голосов
/ 16 февраля 2009

Проверьте, не делает ли какая-нибудь DLL, связанная с вашим exe-файлом, что-то странное в его DLLMain в ответ на уведомления DLL_THREAD_ATTACH.

1 голос
/ 16 февраля 2009

Вы проверили, успешно ли выполняются функции? Возвращаемые значения и GetLastError() могут дать некоторые подсказки, что происходит не так.

1 голос
/ 16 февраля 2009

С http://msdn.microsoft.com/en-us/library/kdzttdcb.aspx

"В случае успеха каждая из этих функций возвращает дескриптор вновь созданного потока; однако, если новый созданный поток завершается слишком быстро, _beginthread может не вернуть действительный дескриптор (см. Обсуждение в разделе« Примечания »). _Beginthread возвращает -1L при ошибке, в этом случае errno устанавливается в EAGAIN, если потоков слишком много, в EINVAL, если аргумент недопустим или неверен размер стека, или в EACCES в случае нехватки ресурсов (например, памяти). _beginthreadex возвращает 0 при ошибке, в этом случае устанавливаются errno и _doserrno. "

Ваша нить выходит быстро, не так ли.

0 голосов
/ 16 февраля 2009

Вы пытались протестировать это с Win32 CreateThread? Это может сузить проблему до ЭЛТ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...