WWW.ИСХОДНИКИ.РУ cpp.sources.ru
java.sources.ru web.sources.ru soft.sources.ru
jdbc.sources.ru asp.sources.ru api.sources.ru

  Форум на исходниках
  C / C++ / Visual C++
  Как корректно завершить Thread?

СПРОСИТЬ  ОТВЕТИТЬ
профайл | регистрация | faq

Автор Тема:   Как корректно завершить Thread?
ServerMouse опубликован 18-09-2001 17:02 MSK   Click Here to See the Profile for ServerMouse   Click Here to Email ServerMouse  
Имею приложение создающее несколько Thread работающих с сокетами. Как заставить threads нормально завершиться (не TerminateThread).
Все нити завершаются если установлен соотв. Event, но если я делаю

SetEvent(CloseEvent);
Sleep(10000);

нити спят вместе с основной. Как побороть?

Heromantor опубликован 18-09-2001 17:24 MSK     Click Here to See the Profile for Heromantor  Click Here to Email Heromantor     
А поток какой интерфейсный или рабчий?
m_fox опубликован 18-09-2001 17:30 MSK     Click Here to See the Profile for m_fox  Click Here to Email m_fox     
можно использовать общую переменную, например которая имеет только 2 состояния 0 и не 0
впринципе для таких случаев подойдет

или используй семафоры.
для евентов надо использовать WaitForSingleObject или waitformiltiobject

ServerMouse опубликован 18-09-2001 17:57 MSK     Click Here to See the Profile for ServerMouse  Click Here to Email ServerMouse     
Объясню чуть подробнее:

HANDLE CloseEvent;
//Главный поток (класс public CDocument)
BOOL CMyDoc::OnNewDocument()
{//Завершаю запущеные потоки
SetEvent(CloseEvent);
Sleep(10000);
ResetEvent(CloseEvent);

//Удаляю соотв. классы.
......
}


//Класс моего рабочего потока, ф-ция потока
//Экземпляров несколько, след. и потоков тоже.
DWORD WINAPI CCafe::SockThread(LPVOID ts)
{
if(WaitForSingleObject(CloseEvent,0)==WAIT_OBJECT_0)
{
shutdown(sock,2);
closesocket(sock);
WSACloseEvent(hEvent);
return 0;
}

if( WSA_WAIT_FAILED != ::WSAWaitForMultipleEvents(1, &hEvent, false,100,false))
{
//Тут мой сокетовый обработчик.
}
......
}

Получается так, что когда я делаю Sleep(10000) мои потоки тоже 'подвисают' и не могут увидеть CloseEvent.

Heromantor опубликован 18-09-2001 18:45 MSK     Click Here to See the Profile for Heromantor  Click Here to Email Heromantor     
Вот мля пока писал предыдущий пост все глюкануло...

if(WaitForSingleObject(CloseEvent,0)==WAIT_OBJECT_0)
Почему тайм-аут = 0? функция вылазит сразу у тебя.

Скорее всего надо так:

HANDLE events[2];

switch(WaitForMultipleObjects(2,events,false,100)
{
case WAIT_OBJECT_0:
shutdown(sock,2);
closesocket(sock);
WSACloseEvent(hEvent);
return 0;

case WAIT_OBJECT_1:
//Тут мой сокетовый обработчик.

case WAIT_TIMEOUT:
AfxMessageBox("TimeOut!!!");
return(-1);
default:
AfxMessageBox("Error!");
return(-1);
}

OlegO опубликован 19-09-2001 10:54 MSK     Click Here to See the Profile for OlegO  Click Here to Email OlegO     
Правильнее ждать убиения потока
ф-ей WaitForSingleObject(YouThreadHandle,...) - она прекратит ждать, когда поток уничтожиться(т.е. YouThreadHandle перейдет в свободное состояние) или по таймауту,
а не Sleep (так как это глупо, от куда ты знаешь что 10 секунд тебе хватит ? )
ServerMouse опубликован 19-09-2001 11:21 MSK     Click Here to See the Profile for ServerMouse  Click Here to Email ServerMouse     
>от куда ты знаешь что 10 секунд тебе хватит ?
2OlegO: Я этого незнаю. Просто если они не завершились я делаю TerminateThread(). И это считаю правильным. Не должно всё приложение зависнуть если у одного из потоков проблемы. Если я сделаю WaitForSingleObject(ThreadHandle, INFINITE); cуществует вероятность того что приложение повиснет тока потому, что какой-то поток ушёл в вечный цикл. Лучше так:
if(WAIT_OBJECT_0!=WaitForSingleObject(ThreadHandle, 500))
TerminateThread(ThreadHandle);

OlegO опубликован 19-09-2001 15:22 MSK     Click Here to See the Profile for OlegO  Click Here to Email OlegO     
Принимается :) так и надо делать, но заметь про INFINITE я ничего не говорил :)
m_fox опубликован 19-09-2001 17:10 MSK     Click Here to See the Profile for m_fox  Click Here to Email m_fox     
Ждать завершения потока надо так:
for(int i=10;i>0;i--)
{
GetExitCodeThread(m_hThread,&dwExitCode);
if (dwExitCode==STILL_ACTIVE)
Sleep(25);
else
break;
}
TerminateThread(...);
С помощью счетчика i и Sleep подбираешь примерное максимальное время реакции твоего потока.

ServerMouse опубликован 19-09-2001 18:04 MSK     Click Here to See the Profile for ServerMouse  Click Here to Email ServerMouse     
Всё, всем спасибо, сделал так:
SetEvent(CloseEvent);
CCafe* pCafe=FirstCafe;
while(pCafe!=NULL)
{
if(WAIT_OBJECT_0!=WaitForSingleObject(pCafe->ThreadID,300))
TerminateThread(pCafe->ThreadID,0);
pCafe=pCafe->GetNextCafe();
}

Работает -- загляденье.

DEiL опубликован 19-09-2001 23:48 MSK     Click Here to See the Profile for DEiL  Click Here to Email DEiL     
ну вы пля уйопки. компы - сакс. забейте. лучше идите пиво пейте :)
Kostik опубликован 20-09-2001 05:25 MSK     Click Here to See the Profile for Kostik  Click Here to Email Kostik     

Ещё один.
LAMO матом крыл. А потом... безвременно покинул сей мир.
Теперь DEiL заряжает.
"Не зарастёт народная тропа."

СПРОСИТЬ  ОТВЕТИТЬ
Перейти:


E-mail | WWW.ИСХОДНИКИ.RU

Powered by: Ultimate Bulletin Board, Freeware Version 5.10a
Purchase our Licensed Version- which adds many more features!
© Infopop Corporation (formerly Madrona Park, Inc.), 1998 - 2000.