Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2006.01.15;
Скачать: [xml.tar.bz2];

Вниз

Многопоточная закачка файлов   Найти похожие ветки 

 
maVladimir   (2005-09-27 20:04) [0]

Здравствуйте, уважаемые кодеры.

Хотелось бы узнать, каким образом работает многопоточная закачка файлов.
То есть, конечно, есть некоторые прикидки насчет того, как это сделать, но все они мне кажутся очень некорректными путями решения этой задачи.

Интересует именно МНОГОПОТОЧНАЯ закачка файлов (дозакачка не требуется по той причине, что файлы небольшие, но их ОЧЕНЬ МНОГО).

И, если, не жалко, выложите немного кода для примера.

Заранее благодарен.


 
S@ska   (2005-09-27 22:40) [1]

http://bexet.boom.ru/page/source.htm


 
maVladimir   (2005-09-28 07:46) [2]

Если имелось в виду http://bexet.boom.ru/arc/src/dnload.rar, то это совсем не то, что хотелось.
Нужна МНОГОПОТОЧНАЯ закачка, то есть создание множества потоков для закачки разных файлов.

Владимир.


 
dmitry501 ©   (2005-09-28 08:07) [3]

maVladimir   (28.09.05 7:46) [2]
Если есть процедурка закачки одного файла, то что мешает запустить ее в несколько потоков?


 
maVladimir   (2005-09-28 08:37) [4]

Мешает отсутствие красивого решения.

Я хотел сделать следующим образом:
Программа выбирает из списка какой-то URL и, если количество запущенных потоков меньше максимума, то запускаем новый поток, который тянет этот URL. В список (TList) запихиваем ссылку на этот поток. Затем после закачки страницы поток передает сообщение основному потоку о том, что страница скачана. Здесь облом! Необходимо из списка потоков удалить ссылку на освобожденный поток, но совершенно непонятно, как узнать, когда уже МОЖНО удалять ее. То есть после закачки поток посылает сообщение и сразу же terminate. Выходит, что потока уже нет, а ссылка в списке еще существует. Можно после приема сообщение от потока через какое-то время удалять его из списка (в надежде на то, что он уже завершил всю свою работу), но это неправильно.

В общем, я не знаю, что я тут понаписал, но решение это некрасивое и неправильное. Понимаю, что работать будет, но хочется узнать, как делают мастера.

Владимир.


 
dmitry501 ©   (2005-09-28 09:01) [5]

>Затем после закачки страницы поток передает сообщение основному потоку о том, что страница скачана.
Страница уже скачана!
>Можно после приема сообщение от потока через какое-то время удалять его из списка (в надежде на то, что он уже завершил всю свою работу), но это неправильно.
Страничка уже скачана! И ссылку можно спокойно удалять.
Это решение представляет из себя простейший диспетчер потоков и вполне красиво...
Странно как-то...


 
maVladimir   (2005-09-28 09:27) [6]

я имею в виду следующее:
constructor TLoadingThread.Create(CreateSuspended: boolean);
begin
 inherited Create(CreateSuspended);
 FreeOnTerminate := true;
 HTTP := TIdHTTP.Create;
end;

destructor TLoadingThread.Destroy;
begin
 HTTP.Free;
 inherited;
end;

procedure TLoadingThread.Execute;
var
 Page: string;
begin
 Page := HTTP.Get("bla");
 Посылаем что скачано в основной поток;
end; //Здесь уже поток обращается к своему деструктору и уничтожается.

Что происходит в основном потоке? Он получает строку с содержащейся в ней скачанной страницей от потока N и ему надо удалить указатель на этот поток из MyThreadList. Так вот, когда он должен это сделать?
Сразу после получения страницы? Но тогда еще поток не освободил свою память.
Послу некоторого времени? Но откуда узнать, что поток все свои дела уже сделал?

Может быть, я, конечно, некорректно поставил вопрос и неумело объяснил его, но все же я старался.

Спасибо за внимание.


 
Seeker ©   (2005-09-28 09:40) [7]


> Так вот, когда он должен это сделать?

В обработчике OnTerminate.


 
dmitry501 ©   (2005-09-28 09:43) [8]

А для чего Вы храните указатели на потоки? Я думал у Вас в списке просто хранятся адреса закачиваемых в данный момент файлов, чтобы их повторно не качать. Да, даже если и там хранится указатель на поток, то все-равно ждать не нужно, если после того как поток отправил сообщение, то он сразу завершается. Или Вы боитесь, что в деструкторе возникнет исключение? Тогда уберите
HTTP := TIdHTTP.Create; из конструктора и
HTTP.Free; из деструктора и перенесите их в Execute потока.
з.ы.
В принципе основной поток процесса и должен выполнять роль диспетчера. Т.е. из кокого-то листа он берет адрес очередного файла для закачки и запускает дополнительный поток, передав ему этот адрес для закачки. Затем этот адрес он перемещает во второй список, в котором хранятся адреса файлов, закачивающихся в данный момент. Получив от потока сообщение об окончании закачки файла перемещает адрес этого файла из второго списка в третий, в котором хранятся адреса уже закачанных файлов. Дополнительный поток никак не зависит от других потоков и просто закачивает файл. Все просто, логично. по вкусу можете считать сколько адресов находится во втором списке, для ограничения кол-во выполняемых потоков, а также обрабатыватьтаймауты и пр.


 
maVladimir   (2005-09-28 10:49) [9]

Указатели на потоки я храню для того, чтобы suspend"ить и resume"ировать их, если это потребуется.
Да, кстати, после того, как пришло сообщение от потока о том, что страница скачана или не скачана (в случае какой-нибудь ошибки), уже можно удалять указатель на этот thread, потому что обращения к нему уже точно больше не будет. Оказывается, что можно вообще не ждать, пока поток завершит свою работу и освободит память. Как-то мне это не приходило в голову. :)

> Seeker.
Write an OnTerminate event handler to execute code after the thread finishes executing.

То есть код в OnTerminate исполняется еще до того, как поток уничтожается, а надо было наоборот.

> dmitry501
Да, кстати, с HTTP := TIdHTTP.Create и HTTP.Free лучше сделать так, как вы посоветовали. Хотя бы чисто из эстетических соображений :).

Спасибо за наведение на хорошие мысли. :)))



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2006.01.15;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.012 c
14-1134920396
begin...end
2005-12-18 18:39
2006.01.15
С Днём рождения! 18 декабря


1-1134121204
AllDontFire
2005-12-09 12:40
2006.01.15
Invalid Thread - где копать?


14-1134210073
SergP.
2005-12-10 13:21
2006.01.15
Даунлоад на php. Подсчет кол-во скачиваний.


6-1122450032
Eugene V.
2005-07-27 11:40
2006.01.15
IdHTTP (Indy 10, Delphi 2005)


14-1134722550
Daria
2005-12-16 11:42
2006.01.15
telnet





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский