|
Модераторы: Snowy, Poseidon, MetalFan |
|
pvabox |
|
||||
Новичок Профиль Группа: Участник Сообщений: 35 Регистрация: 23.8.2009 Репутация: нет Всего: нет |
Уважаемые господа, помогите мне решить одну задачку. Мне необходимо проверять большой массив ссылок StringList на работоспособность.
Это ссылки playlist-а вида http://ott-cdn.../index.m3u8. Необходимо проверить лишь существование ресурса. Код имеет следующий вид:
и обработчик
У этого кода два больших недостатка - он вешает программу и, если сервер долго не отвечает, то поиск прекращается, хотя за это время можно было бы проверить другие ссылки. Поэтому процесс сильно затягивается. Подскажите, как можно преодолеть эти две проблемы в D07? Полагаю, необходимо использовать несколько независимых потоков и если какие потоки зависнут, то другие продолжат работу. Но как это сделать не знаю. А может есть и другие решения? |
||||
|
|||||
Alexeis |
|
|||
Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 2 Всего: 459 |
Вы все правильно решили. Можно создавать хоть 100 потоков. В разделе WinApi есть прибитая статья "Многопоточность - как это делается в Дельфи. Не используйте потоки, не прочитав это". Оттуда можно стрельнуть примерчик работы.
Можно обойтись из без потоков, но для этого нужно искать классы для работы в асинхронном режиме. Технически в вашем случае не обязательно даже дожидаться ответа. Можно послать 100 запросов и раз в секунду пробегаться и проверять у каждого не пришел ли ответ. Но насколько я помню, IdHTTP так не умеет. Так умеют обычные сокеты (каждый сокет имеет свой буфер, который винда заполняет ответом от сетевой карты по мере прихода данных, так что не обязательно прям ловить момент прихода ответа). -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
pvabox |
|
|||
Новичок Профиль Группа: Участник Сообщений: 35 Регистрация: 23.8.2009 Репутация: нет Всего: нет |
Спасибо за ответ. Статью "Многопоточность - как это делается в Дельфи. Не используйте потоки, не прочитав это" я конечно же читал, но разобраться как реализовать мою задачу в коде так и не понял. В статье описаны все тонкости использования потоков, а какой вариант выбрать мне я так и не понял.
Если кто может помогите! |
|||
|
||||
Alexeis |
|
|||
Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 2 Всего: 459 |
Да хоспади, тут же не нужно никакой синхронизации даже делать. Передал в конструкторе, вернул в деструкторе. Просто вызвать функцию изнутри Execute потока так как она есть.
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
pvabox |
|
|||
Новичок Профиль Группа: Участник Сообщений: 35 Регистрация: 23.8.2009 Репутация: нет Всего: нет |
Круто! Я б до этого не допер. Спасибо, буду разбираться с кодом.
|
|||
|
||||
pvabox |
|
|||
Новичок Профиль Группа: Участник Сообщений: 35 Регистрация: 23.8.2009 Репутация: нет Всего: нет |
Alexeis, Вы предложили простой и отличный вариант решения задачи. Но у меня есть несколько вопросов:
- Подскажите, а на каком этапе данные из urlList потока передаются в urlList формы, т.е. обратно в основной поток? - Если urlList содержит около 300 адресов, то получается будет создано столько же потоков, а как переписать этот код
чтобы создавалось не более MAX_THREADS потоков? |
|||
|
||||
Alexeis |
|
|||
Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 2 Всего: 459 |
pvabox, в данном случае нет 2х списков. Объект TStringList это и есть указатель на объект. Передача объекта это по сути передача указателя. Он тупо общий.
Код будет устойчиво работает, если не меняется количество элементов списка, поскольку поток производит чтение url без синхронизации. Просто запись результатов осуществляется в деструкторе, а деструктор отрабатывает уже в главном потоке. Поэтому нет никакой необходимости в синхронизации. Самый простой вариант как сделать ограничение это разбить TStringList на несколько списков, чтоб каждый список был меньше MAX_THREADS. И проверять каждый список по очереди. Я бы даже уменьшил количество потоков до 100. Вряд ли при количестве больше 100 будет прирост. Скорее всего накладные расходы на обслуживание 300 потоков перекроют пользу от параллельности. Сетевая карта у вас одна, хорошо если соединение гигабитное и она успеет все это быстро отправить, иначе просто образуется длинная очередь из запросов к серверам. Ваша цель состоит в том, чтобы успеть отправить столько запросов, что они все успеют уйти до тех пор пока первые ответы сервера начнут уже приходить. Когда придут первые ответы процессор переключиться на их обработку. Более сложное решение потребует создания пула потоков. Т.е. мы создает примерно 100 потоков и не завершаем их при приходе ответа, а лишь синхронизируем ответ (функция Synchronize), после чего дает этому потоку новый url. В этом случае всегда будут загружены все 100 потоков. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
pvabox |
|
|||
Новичок Профиль Группа: Участник Сообщений: 35 Регистрация: 23.8.2009 Репутация: нет Всего: нет |
Alexeis, в коде используется метод WaitFor, который вешает программу, пока не получит ответ. Если в конструкторе прописать
то как тогда запустить деструктор, если метод Free "в ручную" вызываться не будет? Это сообщение отредактировал(а) pvabox - 24.3.2019, 11:25 |
|||
|
||||
pvabox |
|
|||
Новичок Профиль Группа: Участник Сообщений: 35 Регистрация: 23.8.2009 Репутация: нет Всего: нет |
Результаты тестов - 400 рабочих ссылок (400 потоков) время проверки около 3 секунд на скорости соединения с интернетом 40 Мб/с. Если ссылки не рабочие, то на время проверки программа виснет напрочь, даже окно не двигается.
Полагаю, что в деструкторе необходимо производить проверку, не является ли данный поток последним и если да, то запустить, например процедуру ThreadsCompleted основного потока и продолжить работу программы. Может существует более простой метод? Подскажите пожалуйста. |
|||
|
||||
pvabox |
|
||||
Новичок Профиль Группа: Участник Сообщений: 35 Регистрация: 23.8.2009 Репутация: нет Всего: нет |
Мм..., похоже общаюсь на форуме сам с собой , короче вот что получилось:
Но появилась новая проблема. При большом количестве запросов истекает время ConnectTimeout и возникает исключение, хотя ссылка рабочая. Придется ограничивать число потоков. |
||||
|
|||||
RAIN666 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 18 Регистрация: 15.2.2019 Репутация: нет Всего: нет |
Я сейчас схожим вопросом занимаюсь.
Почему вы для проверки не используете WinAPI функции? Оно же быстрее должно быть. что-нибудь типа этого:
не подойдёт? |
|||
|
||||
pvabox |
|
||||
Новичок Профиль Группа: Участник Сообщений: 35 Регистрация: 23.8.2009 Репутация: нет Всего: нет |
Пасиба, RAIN666, я бы написал так:
или так:
попробую, потом отпишусь. Это сообщение отредактировал(а) pvabox - 26.3.2019, 14:26 |
||||
|
|||||
_zorn_ |
|
||||
Эксперт Профиль Группа: Завсегдатай Сообщений: 1077 Регистрация: 21.8.2007 Репутация: нет Всего: 12 |
Спамеры пошли дальше... Добавлено через 1 минуту и 58 секунд
Мне нравится это "должно быть" А сам замерить не хочешь ? Чтобы юзать уродское WinAPI должны быть более веские поводы чем "должно быть". |
||||
|
|||||
pvabox |
|
|||
Новичок Профиль Группа: Участник Сообщений: 35 Регистрация: 23.8.2009 Репутация: нет Всего: нет |
Почему же сразу спамеры, я для себя решил написать программку типа IPTV M3U Editor, которая работает с IPTV плей-листами и, в том числе проверяет работоспособность ссылок. Вот и обратился с вопросами оптимизации С WinAPI дельфя кучу предупреждений выдает. |
|||
|
||||
pvabox |
|
||||
Новичок Профиль Группа: Участник Сообщений: 35 Регистрация: 23.8.2009 Репутация: нет Всего: нет |
Провел эксперимент, с WinAPI код в экзешнике на 120 кб меньше, но работает на четверть времени дольше, поэтому остановился на компоненте Indy. Проверку организовал в 20 (параметр задается) потоков, работает очень быстро, программу не вешает вообще, даже прокрутка списка во время проверки не тормозит. Поставленная задача решена полностью!
Вот пример метода проверки ссылок в N потоков, который я использовал:
и модуль потока
Всем спасибо за помощь! Ну и вот что получилось, может кому пригодиться Это сообщение отредактировал(а) pvabox - 4.4.2019, 13:27 Присоединённый файл ( Кол-во скачиваний: 4 ) Test.zip 344,08 Kb |
||||
|
|||||
Правила форума "Delphi: Сети" | |
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делится вскрытыми компонентами
Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Сети | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |