2011-01-27 2 views
1

Я создаю поток, которому в качестве аргумента передается пустота * структуре. Эта структура создается в классе. Когда вызывается этот деструктор класса, который находится в конце main, структура удаляется. Поэтому позже я вижу, что дочерний поток запускается снова, и ссылаясь на его аргумент void *, выдает исключение, поскольку оно уже освобождено. Я надеялся, что дочерние потоки выйдут до вызова деструкторов, но этого не происходит.C++ Многопоточность - Когда заканчивается дочерний поток?

С ExitThread страницы в MSDN,

Однако в коде C++, нить вышли до того, как деструкторы могут быть называется или любая другая автоматическая очистка может быть выполнены.

Каковы деструкторы, на которые ссылается указанная выше линия?

Резьбовая нить выполняет процедуру, которая имеет срок службы основного потока. Используя глобальный флаг, я думал, что могу контролировать выполнение дочернего потока. Я устанавливаю глобальный флаг в последней процедуре, выполняемой основным потоком. Но глобальные объекты освобождаются до завершения дочернего потока. В этом случае даже это не поможет мне.

Подводя итог, как наилучшим образом я могу выйти из дочернего потока, который имеет жизненный цикл основного потока? Я не хочу использовать terminatethread api.

Edit: Некоторые примеры кода

// В способе в конце основного

void EndofMain() 
{ 
WaitForSingleObject(globalObj->hMutex, INFINITE) 
globalObj->threadActive = false; 
ReleaseMutex(globalObj->hMutex); 
} 

void ChildThreadProc(void* data) 
{ 
while(globalObj->threadActive) 
{ 
    WaitForSingleObject(globalObj->hMutex, INFINITE) 
    //do other stuff 
    ReleaseMutex(globalObj->hMutex); 
    sleep(1000); 
} 
} 

Теперь есть шанс, где globalObj удаляется и затем дочерний поток называется?

+3

C++ еще не имеет поддержки многопоточности. Это означает, что вы используете библиотеку: boost, pthreads, win32 threads или какое-то расширение поставщика: msbc _beginthreadex api, например. Скажите, пожалуйста. –

+0

msvc's _beginthreadex api .. – excray

ответ

1

Один из вариантов заключается в том, чтобы основной поток сигнализировал дочерний поток, что он должен выйти (возможно, установив логический флаг), а затем используя WaitForSingleObject в конце main(), чтобы дождаться завершения потока перед возвратом и называя деструкторов. Это предотвращает описанную вами ошибку, заставляя поток выходить (безопасным образом) перед тем, как уничтожить деструкторы.

+0

Я устанавливаю булевский флаг в конце main. Но как WaitForSingleObject гарантирует прекращение потока? – excray

+0

'WaitForSingleObject (threadHandle, INFINITE)' не возвращается, пока поток не завершится (если только непредвиденная ошибка). Эта ссылка дает пример и полезное описание: http://www.codeproject.com/KB/cpp/rendevouz.aspx –

+0

@Vivek, о чем упоминалось в Templatetypedef, было то, что дескриптор, который вы передаете WaitForSingleObject, должен быть * дескриптором потока * , Вот как WaitForSingleObject гарантирует, что поток завершен - он не вернется, пока поток не завершится. Поток должен периодически проверять флаг, и если он установлен, потоку необходимо как можно скорее выйти. Обычно это делается просто путем возврата из threadproc, а не путем вызова ExitThread. –

Смежные вопросы