|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
Опции темы | Поиск в этой теме |
20.04.2014, 00:53 | #1 |
Форумчанин
Регистрация: 18.10.2010
Сообщений: 419
|
TThread и WaitForSingleObject
Добрый вечер, друзья =)
У меня возникли проблемы, которые я даже затрудняюсь внятно описать. Пока пытаюсь разобраться самостоятельно, но не могли бы вы прокомментировать, правильно ли я использую указанные штуки. Я делаю компонент который должен скачать указанную ссылку. Непосредственно для скачивания используется компонент TidHTTP (запрос Get). Задумка такова: нужно реализовать систему, работу которой можно было бы прекратить, независимо от ее состояния (чтобы в случае чего прога не повисала намертво). ИМЕННО для этого создается поток, в котором и выполняются TidHTTP.Get(link) в случае отсутствия результатов в течении указанного времени поток просто убивается и программа продолжает свою работу Но при этом основной код не должен выполняться параллельно с потоком, т.е. после запуска потока надо дождаться завершения его работы и только после этого продолжить выполнение основного кода. Для этого я использую функцию WaitForSingleObject, которая ждет событие, которое активируется в конце работы потока. алгоритм такой: 1. создаем событие 2. создаем и запускаем поток 3. ждем "чуда" 4. поток подходит к концу и активирует "чудо" 5. продолжаем основной код вот как реализовано: 1. Event:=CreateEvent(nil, True, False, nil); // создаем событие (ручной сброс, сброшено) 2. TR:=TThread.Create; // создаем и запускаем поток TR.Resume; 3. WaitForSingleObject(Event, 5000); // ждем чуда (при этом поток по-идее работает паралельно) 4. код, выполняемый в потоке: procedure Execute; begin TidHTTP.Get(link); // выполняем необходимые действия PulseEvent(Event); // активируем "чудо" end; По-моему здесь все логично, но возникают проблемы, причем с определенной закономерностью: как правило выполняется пара тысяч запросов, а потом что-то слетает и все остальные запросы проскакивают мгновенно - как будто "чудо" активируется сразу при запуске потока. Я грешил на то, что это из-за того, что не удаляю событие после использования, я это исправил, но проблема не исчезла. Что касается всего остального - весь объект удаляется и создается по-новой на каждый запрос. В процессе ковыряния в проблеме пробовал такой вариант: вызывать PulseEvent(Event); не в конце потока, а в процедуре по завершении (OnTerminate). в результате поток не начинал свою работу, пока не пройдет таймаут ожидания ( 5000 ms ). В общем скажите, что я не учел? Может я не знаю каких-то нюансов? Последний раз редактировалось xrob; 20.04.2014 в 13:50. |
20.04.2014, 02:04 | #2 | |
ПШП
Участник клуба
Регистрация: 15.07.2013
Сообщений: 1,894
|
Цитата:
|
|
20.04.2014, 13:54 | #3 |
Форумчанин
Регистрация: 18.10.2010
Сообщений: 419
|
northener, вы полностью читали первый пост, или частично?
специально для вас, и всех, кто не понимает зачем здесь поток, я выделил место, в котором объясняется зачем. Но как бы там ни было, вопрос то все-таки не про поток, а про CreateEvent, WaitForSingleObject и PulseEvent: что я делаю не так? Для тех, кто считает, что я "хочу странного", объясню ход своих мыслей. Я исхожу из двух фактов: 1. TidHTTP может зависнуть намертво. 2. Обломы допустимы, по прога должна работать нисмотря ни на что. представьте такую ситуацию: вам необходимо 100 раз выполнить следующую процедуру: procedure FateChallenge; var c,d:integer; begin d:=Random(1); if d=0 then c:=5; if d=1 then while true do begin end; end; есть смельчаки? Последний раз редактировалось xrob; 20.04.2014 в 14:06. |
20.04.2014, 13:56 | #4 |
Старожил
Регистрация: 26.04.2008
Сообщений: 2,645
|
А может чуда и нет?
Если такая закономерность наблюдается при достаточно большом запуске потоков, то предположу следующее. Помню в старом Паскале была такая фишка - если выделять память, а потом её освобождать, то скоро память кончается из-за того, что она не возвращалась в кучу. Учитывая это, можно предположить, что и в Delphi (а там свой менеджер памяти) есть эта проблема. Не скажу точно, но причина может быть в том, что API функции и дельфийский потоки используют разные менеджеры памяти что и приводит к утечке памяти, невозможности создать событие по причине ограничения их числа или чего-то подобного. Вобщем надо смотреть в сторону памяти чем-то вроде http://technet.microsoft.com/en-us/s...rnals/dd535533 Кстати, зачем пересоздавать всё каждый раз? Пусть будет програма(основной поток) и ещё один поток (для загрузки). И переключаться между ними сигналами или любым другим известным способом. Я инди почти не использую, но (если память не изменяет) там есть антифриз, который не замораживает форму при скачивании файла. Правда, говорят с ним что-то не так |
20.04.2014, 14:13 | #5 |
Форумчанин
Регистрация: 18.10.2010
Сообщений: 419
|
eoln, спасибо, вы подкинули интересную идею, если предположить, что вы правы, то гармонично это вписывается в ситуацию.
у меня запрос идет в try и получается так, что я создаю TidHTTP, а он не создается, потому что памяти не хватает, а потом я в try пробую делать запрос, соответственно это мгновенно заканчивается провалом. + к тому же, стоит перезапустить прогу - все снова работает. полез проверять теорию =) а по поводу антифриза я, конечно, точно не знаю, но предполагаю, что он работает так: while true do Application.ProcessMessages; =D Последний раз редактировалось xrob; 20.04.2014 в 14:18. |
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Не срабатывает waitforsingleobject | peeper | Общие вопросы Delphi | 2 | 28.11.2013 16:10 |
При освобождении обьекта TThread, он вешает всю программу. При этом код Execute у TThread уж выполнился.. | Человек_Борща | Общие вопросы Delphi | 23 | 30.11.2011 09:18 |
Многопоточность showmodal и WaitForSingleObject | bulldog5293 | Общие вопросы Delphi | 24 | 24.01.2011 18:46 |
WaitForSingleObject | besserebrenik | Win Api | 3 | 15.02.2010 22:40 |
WaitForSingleObject в Delphi 2009 | Хамяг | Win Api | 11 | 03.12.2009 09:06 |