|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
Опции темы | Поиск в этой теме |
02.03.2010, 17:31 | #1 |
Пользователь
Регистрация: 01.11.2007
Сообщений: 19
|
Если остановился поток (TThread). Как перезапустить без потери памяти
Здравствуйте, уважаемые
Прошу помощи, уже замучался совершенно Описание: существует огромный проект (с многопоточностью), в нем используются IdHTTP c TIdIOHandlerSocket и TIdSocksInfo (для работы через socks4/5) Использую Indy9 (обновлять не могу, уже привык к существующим ошибкам в этой либе (с которыми знаком)) Время от времени соксы умирают, но проблема в том, что поток при этом не двигается дальше. В варианте с простыми HTTP Proxy я мог сделать IdHTTP.DisconnectSocket и это решало проблему - Get (Post) прерывали свою работу и поток работал дальше. Но при подключении TIdIOHandlerSocket и TIdSocksInfo этот вариант больше не срабатывает (ошибок не возникает, поток просто останавливается и находится в подвисшем состоянии до остановки программы). Собственно вопрос: Как можно убить подвисший поток (рассмотрю любые альтернативные варианты к данной ситуации)? Острые моменты: 1. При попытке пересоздания экземпляра класса безвозмездно теряется память. 2. Возникает Access Violation (что совершенно логично) Подскажите, пожалуйста, выход из ситуации. За ранее огромное спасибо! |
28.01.2011, 21:00 | #2 |
Пользователь
Регистрация: 03.02.2009
Сообщений: 20
|
И мне это тоже нужно, вернее как перезапустить отработанный поток, чтоб не потерялись данные, хотя можно и с потерями, главное не пересоздавать, а просто перезапустить его Execute?
|
28.01.2011, 21:46 | #3 |
Android Developer
Старожил Подтвердите свой е-майл
Регистрация: 19.02.2007
Сообщений: 3,708
|
В потоке делаем цикл. Создаем мютекс. Ставим на вечное ожидание через WaitForSingleObject. В месте в котором где нужно перезапустить поток устанавливаем мютекс потока, что в свою очередь даст отработать WaitForSingleObject и поток в очередной раз выполнит итерацию цикла.
|
30.01.2011, 12:32 | #4 |
php / delphi
Форумчанин
Регистрация: 10.06.2007
Сообщений: 175
|
+1. Потоку не нужно давать отрабатывать (завершиться).
Можно и без Мьютексов (правда с двумя флагами) при помощи нехитрой конструкции: Код:
G.Azamat { Web Development / Computer simulation }
Начинающий программист думает, что в килобайте 1000 байтов, а законченный уверен, что в километре 1024 метра. |
30.01.2011, 13:01 | #5 |
Android Developer
Старожил Подтвердите свой е-майл
Регистрация: 19.02.2007
Сообщений: 3,708
|
Код:
1. Велосипед 2. Повесит поток, загрузит на 100% Почему мютекс: 1. Системное решение 2. Останавливает поток на время, в ожидании сигнала от мютекса |
30.01.2011, 13:20 | #6 | ||
php / delphi
Форумчанин
Регистрация: 10.06.2007
Сообщений: 175
|
Не спорю - действительно Велосипед.
Цитата:
Флаг РазрешитьВыполнение предполагается использовать только совместно с Suspended. Никто и не предлагает крутить поток вхолостую. Для этого и привел соответствующие методы управления потоком. При их использовании поток вхолостую крутится лишь незначительное время. Цитата:
G.Azamat { Web Development / Computer simulation }
Начинающий программист думает, что в килобайте 1000 байтов, а законченный уверен, что в километре 1024 метра. |
||
30.01.2011, 13:59 | #7 | |
Android Developer
Старожил Подтвердите свой е-майл
Регистрация: 19.02.2007
Сообщений: 3,708
|
Цитата:
|
|
31.01.2011, 13:31 | #8 | |||
Старожил
Регистрация: 28.01.2009
Сообщений: 21,000
|
Цитата:
Цитата:
Цитата:
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел. Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите. |
|||
01.02.2011, 07:44 | #9 |
Пользователь
Регистрация: 01.11.2007
Сообщений: 19
|
Здравствуйте, Пепел Феникса
Из ситуации я вышел обходным путем, в корне исключив использование библиотеки Indy в cвоих проектах и изменил подход в плане организации структуры многопоточных проектов. Но на поставленный мной выше вопрос я до сих пор не смог бы ответить. Вижу в этом вопросе вы значительно эрудированнее меня, поэтому поясню ситуацию на пальцах, надеюсь вы укажите мне на мои ошибки. Итак, внутри потока: Код:
теперь представим, что у меня 100 экземпляров этого класса и каждый получает сокс для проверки. После завершения работы экземпляр пересоздается и так далее. Если качество наших соксов превосходное, то даже за несколько часов работы мы не увидим роста выделенной памяти под процесс. Другое дело, когда проверяться начинают доступные в паблике и очень плохого качества соксы - тут и начинаются проблемы. Уже через несколько минут видим, что работают не все наши 100 потоков, а лишь какая-то малая часть из них. Причем можно отследить как выполнение в потоке доходит до функции: Код:
Замечу очень важный момент: свойства Timeout игнорируются в принципе, а DisconnectSocket попросту не работает когда мы используем соксы (подключая TIdSocksInfo и TIdIOHandlerSocket). Останавливаем перезапуск потоков, видим на счетчике 87 активных потоков и уходим на пару часов. Возвращаемся, и на счетчике видим примерно тоже число незавершившихся потоков. Что делать? Что тут в принципе можно сделать? Вариантов перепробовал море, все что приходиол только в голову. TerminateThread ? - теряется память Попытка сделать MyThread.Free ? - ерунда и глупость MyThread.HT.Free MyThread.io.Free MyThread.sock.Free ? - получаем Access Violation. Почему я сказал, что - это логично? Потому что они работают в текущий момент. Но проблема не в ошибке, а в том что теряем память. И что у меня получается ошибочным в таком построении класса и где я не прав? Главное - как завершить такой поток не потеряв при этом память? |
01.02.2011, 13:57 | #10 |
Старожил
Регистрация: 28.01.2009
Сообщений: 21,000
|
Код:
салатовое в деструктор. там же вы можете поместить поля для хоста и порта. итого: Код:
проверить не могу, у меня нет ни инди, ни проксь Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел. Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите. |
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Как оповестить основной поток о каком-то событии в потоке (TThread)? | TwiX | Общие вопросы Delphi | 2 | 11.02.2010 02:57 |
Delphi: как поместить анимацию (без звука) в отдельный поток? | ex.cluz | Помощь студентам | 0 | 15.01.2010 14:26 |
Отобразить рабочий поток (TThread) | NervniiJ | Общие вопросы Delphi | 0 | 10.01.2010 17:34 |
Убрать точки без потери данных | king13 | Microsoft Office Excel | 4 | 07.10.2009 13:54 |
Копирование таблицы без потери форматирования | k1r1ch | Microsoft Office Excel | 3 | 09.07.2009 11:00 |