Сначала внимательно прочитайте проблему.
Существует рабочий поток, который создается из класса CreateInstance класса CTest.Вот прототип класса.hThread - это дескриптор потока, а hEventShutdown - это событие, используемое для отключения потока при выходе из программы.WaitForShutdown - это открытая функция, которая используется для сигнализации hEventShutdown и ожидания дескриптора потока, пока поток не выйдет изящноWaitForShutdown вызывается из Exit of Application.
//pseudocode
CTest
{
public:
CTest* CreateInstance();
static threadproc(void *pv);
void WaitForShutdown();
public:
HANDLE hThread;
HANDLE hEventShutdown;
}
void CTest::CTest* CreateInstance()
{
// spawn a thread, pass 'this' pointer to thread , use beginthreadex
hThread = beginthreadex ( threadproc, this );
}
unsigned int CTest::threadproc( void *pv)
{
Ctest *ptest = (Ctest*)pv;
do
{
HANDLES hArray[2] = { pv->hEventShutdown, someotherhandle }
dwResult = Waitformultipleobjects( hArrary , 2);
if ( dwResult == WAIT_OBJECT_0)
delete pTest; // since it is allocated dynamically ( This is required due to some known reasons in my code)
if(dwResult == WAIT_OBJECT_0 + 1)
Doprocessing(); //DoProcessing when other thread signal someotherhandle
}while (1)
void CTest::WaitForShutdown()
{
SetEvent ( hEventShutdown);
WaitForSingleObject ( hThread,INFINITE);
}
void CTest::~CTest()
{
Closehandle(hThread)
Closehandle(hEventShutdown);
}
Теперь, если вы внимательно посмотрите на код, вы обнаружите, что событие передается из функции WaitForShutdown, поток выходит из WaitForMultipleOjbects и удаляет указатель CTest.Это означает, что вызывается деструктор CTest, который, очевидно, закроет дескриптор потока (hThread).Но WaitForSingleObject из WaitForShutdown фактически ожидает дескриптор потока.Так что здесь поведение будет неопределенным (я так думаю, вы можете исправить меня, если я ошибаюсь).Другая проблема заключается в том, что деструктор Ctest вызывается, когда WaitForSingleObject ожидает своего члена hThread, что неверно.Я не могу удалить delete pTest из потока, так как он должен быть там по некоторым причинам.
Как вы предложите решение выше?
Пара решений, о которых я могу подумать:
- Я могу сохранить дескриптор потока на другой карте, но я не хочу этого делать.
- Я могу скопировать потокобработать некоторую локальную переменную перед WaitForSingleObject в WaitForShutdown и будет ждать ее.Не знаю, правильно ли это?Вы говорите мне.
- Или я буду использовать API Duplicatehandle, чтобы получить ссылку на существующий дескриптор потока перед WaitForSingleObject и ждать его.Не знаю, правильно ли это.Не знаю, останется ли дублирующий дескриптор живым после CloseHandle на оригинале.
- Я сохраню идентификатор потока, получаю дескриптор потока из идентификатора потока и буду ждать в дескрипторе потока в WaitForShutdown.Это выглядит более элегантно, но я не знаю, есть ли способ получить дескриптор из идентификатора потока.
Поправьте меня.
Ваш отзыв приветствуется.