Автор
|
Тема: Как корректно завершить Thread?
|
ServerMouse |
опубликован 18-09-2001 17:02 MSK
Имею приложение создающее несколько Thread работающих с сокетами. Как заставить threads нормально завершиться (не TerminateThread). Все нити завершаются если установлен соотв. Event, но если я делаюSetEvent(CloseEvent); Sleep(10000); нити спят вместе с основной. Как побороть?
|
Heromantor
|
опубликован 18-09-2001 17:24 MSK
А поток какой интерфейсный или рабчий? |
m_fox
|
опубликован 18-09-2001 17:30 MSK
можно использовать общую переменную, например которая имеет только 2 состояния 0 и не 0 впринципе для таких случаев подойдетили используй семафоры. для евентов надо использовать WaitForSingleObject или waitformiltiobject |
ServerMouse
|
опубликован 18-09-2001 17:57 MSK
Объясню чуть подробнее: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
Вот мля пока писал предыдущий пост все глюкануло...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
Правильнее ждать убиения потока ф-ей WaitForSingleObject(YouThreadHandle,...) - она прекратит ждать, когда поток уничтожиться(т.е. YouThreadHandle перейдет в свободное состояние) или по таймауту, а не Sleep (так как это глупо, от куда ты знаешь что 10 секунд тебе хватит ? )
|
ServerMouse
|
опубликован 19-09-2001 11:21 MSK
>от куда ты знаешь что 10 секунд тебе хватит ? 2OlegO: Я этого незнаю. Просто если они не завершились я делаю TerminateThread(). И это считаю правильным. Не должно всё приложение зависнуть если у одного из потоков проблемы. Если я сделаю WaitForSingleObject(ThreadHandle, INFINITE); cуществует вероятность того что приложение повиснет тока потому, что какой-то поток ушёл в вечный цикл. Лучше так: if(WAIT_OBJECT_0!=WaitForSingleObject(ThreadHandle, 500)) TerminateThread(ThreadHandle); |
OlegO
|
опубликован 19-09-2001 15:22 MSK
Принимается :) так и надо делать, но заметь про INFINITE я ничего не говорил :) |
m_fox
|
опубликован 19-09-2001 17:10 MSK
Ждать завершения потока надо так: 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
Всё, всем спасибо, сделал так: 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
ну вы пля уйопки. компы - сакс. забейте. лучше идите пиво пейте :) |
Kostik
|
опубликован 20-09-2001 05:25 MSK
Ещё один. LAMO матом крыл. А потом... безвременно покинул сей мир. Теперь DEiL заряжает. "Не зарастёт народная тропа." |