Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Потоки - их завершение и удачная архитектура сервера  (Прочитано 10454 раз)
0 Пользователей и 5 Гостей смотрят эту тему.
Tomek
Гость
« : 13-04-2005 10:48 » 

Привет всем!
В общем, есть многопоточный прокси ;в структуре
Код:
struct {
  HANDLE hThread;
  SOCKET sSource;
  SOCKET sDest;
  int status;
  int nom;
} REC;
хранится дескриптор потока, который будет обслуживать соединение между сокетами sSource и sDest, потом статус потока и его порядковый номер. Создавая новый поток, я передаю ему в качестве параметра вот такую структурку. В самом потоке, он себе использует дескрипторы сокетов, передает и принимает нужные данные; пускай теперь например я устанавливаю каким-то образом глобальную переменную bShutDown, которая должна остановить весь сервер. Вот теперь меня интересует, как правильно-то его завершить ? Создаю я его по _beginthreadex , значит должен завершать (чтобы ресурсы корректно освободить) _endthreadex, — а тогда как мне закрыть дескриптор сего потока ? Как понятно из вышенаписанного, его дескриптор передается в структуре в параметре, следовательно, руки просто чешутся, чтобы закрыть его прямо в самом потоке, присвоить дескрипотору NULL и статус ячейки массива (используется массив типа REC) как свободной. Вот-с.... А есть мысль использовать в "потоке-родителе" WaitForMultipleObject и ждать пока хотя бы один из "потоков-потомков" не завершиться и тогда закрыть его дескриптор. И еще можно тупо циклически опрашивать весь массив структур, и там где скажем статус соответсвующего потока как "ПРИОСТАНОВЛЕННЫЙ" просто закрывать дескриптор и тогда присвоить этой ячейке статус "свободной".

И вторая часть вопроса. А нельзя ли при надобности завершения сервера тупо TerminateThread всем запущенным потокам сделать ? Или все же ждать до INFINITE в вызове WaitForSingleObject пока соответствующий поток сам успешно не завершиться .....
Записан
doublebug
Гость
« Ответ #1 : 13-04-2005 13:22 » 

1 при корректном заверщении потока _endthreadex вызовется сама (после того как вернется из твоей функции).
Тебе только остается закрыть хендл полученный от _beginthreadex ибо _endthreadex не закрывает его.

2 по идее надо подождать какоето время за которое поток должет завершиться сам ну и по наступлению таймаута можно его грохнуть через TerminateThread. Откликаемость потока на флажок завершения зависит от того как ты сделаешь работу с сокетом.

Записан
Hooter
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 14-04-2005 15:25 » 

А нельзя ли при надобности завершения сервера тупо TerminateThread всем запущенным потокам сделать ? Или все же ждать до INFINITE в вызове WaitForSingleObject пока соответствующий поток сам успешно не завершиться .....

Можно сделать всё, что угодно и как угодно... Если ты пишешь прогу для себя. Ага

А если серьезно, то вызвав TerminateThread, ты столкнешься с проблемой неосвобожденной памяти, выделенной в потоке, недеинициализированных устройств и прочих и прочих... Кто, например, закроет сокет, открытый в потоке?. Так что, если ты хочешь, чтобы твоя прога работала стабильно, то тебе придется искать пути _корректного_ завершения потока.

Я обычно делаю следующее: как правило потоки, работающие длительное время, представляют собой бесконечный цикл. Для выхода из такого цикла я обычно использую либо тупой булевский флаг, значение которого изменяется в главном окне при выходе, или же использую объект event, создаваемый с помощью функции CreateEvent. Если у тебя один поток, то и первый способ сойдет. Если потоков два и больше, то лучше все делать через объекты синхронизации (например, event).

ЗЫ. Кстати, о сокетах. Существует способ, чтобы сокет сразу отдавал управление проге, даже если он не завершил выполнение текущей операции (например, операции чтения). Такой режим называется асинхронный. В этом случае тебе не надо будет ждать, пока управление вернется в поток.
Записан
Tomek
Гость
« Ответ #3 : 14-04-2005 16:34 » 

Цитата
Кстати, о сокетах. Существует способ, чтобы сокет сразу отдавал управление проге, даже если он не завершил выполнение текущей операции (например, операции чтения). Такой режим называется асинхронный. В этом случае тебе не надо будет ждать, пока управление вернется в поток.

Да вообще мне интересно, а не проще ли WSAAsyncSelect делать, и каждый раз по прибытии или отправке данных будет приходить событие моему окну ! Но что-то очень подозрительно просто как-то. Все таки с потоками наиболее как мне кажется изящно и легко масштабируемо, да и если окна нет то только потоки....
Что кто думает  по поводу ПРАВИЛЬНОЙ реализации серверов на основе сокетов?
Записан
Hooter
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 14-04-2005 16:51 » 

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

Но лично мое мнение такое: там, где можно придерживаться стандартов - придерживаться их обязательно.
Все, что придумывает microsoft, конечно, классно. Но не майкрософтом единым жив программист Улыбаюсь
« Последнее редактирование: 14-04-2005 17:01 от Hooter » Записан
Hooter
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 14-04-2005 17:02 » new

Вот тут народ о правильном завершении потоков разговаривает: https://forum.shelek.ru/index.php/topic,5228.0.html
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines