Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Perl: Общие вопросы > Многопоточность |
Автор: Bulat 22.8.2007, 17:03 | ||
Вот пришлось создать грамотное многопоточное приложение. Почти весь день убил, неоднократно пытался найти что-то с форума что могло бы помочь, в итоге собрал по кусочкам, ИМХО не было ни одной темы, которая давала ответы на все вопросы поставленные мною для решения задачи. Сама задача заключалась в том, что есть список(от маленького до очень большого) данных, которые обрабатываются медленно, при этом нам нужно чтоб каждый дочерный процесс обрабатывал каждый раз новые данные из списка, т.е. чтоб не произошло ситуации, что два дочерних потока обрабатывают одни и теже данные. И под конец, количество дочерних потоков должно быть всегда не более чем заранее заданного числа, которое может быть меньше чем количество обрабатываемых данных. И еще не надо забывать про проблему с "зомби", о которой писалось почти в каждой мною просмотренной теме. Вот в итоге цельный небольшой пример, для тех кто в будущем будут сталкиваться с подобными задачами. Чтоб не пришлось как и мне искать и собирать все по кускам ![]()
с индексами можно повертеть, покрутить как кому угодно. Если кто-то найдет неточность или ошибку, буду рад послушать, так как сам использую данный алгоритм ![]() |
Автор: Nab 22.8.2007, 17:38 | ||
хех, была похожая задача, решал гдето около года назад... у меня было допущение, что обмена данными между детьми и головным процессом не будет, поэтому скрипт не отслеживает поведение детей, он просто завершаеться когда завершаться все дети. Скриптик проверки проксей на работоспособность, это чтоб коментарии были понятны ![]() Прошел проверку временем, ибо до сих пор стоит и работает, и каждые пол часа выдает список рабочих проксей. ![]()
В итоге скрипт просто завершался когда завершались все дети... с зомби проблем не было... да и неоткуда им было взяться... Зато главный результат был достигнут, помк проксей ускорился в 15 раз ![]() |
Автор: Bulat 3.9.2007, 19:32 | ||
Чуточку переделал код, относительно тех строк, которые киляют "зомби". Этот скрипт будет работать очень хорошо и в таком виде. Дело в том, что в своих скриптах, у меня возникли небольшие проблемы, относительно "долговисящих", дочерних процессов. Я не знаю связано ли это конкретно с обработкой данного сигнала, у меня в скриптах есть обработка не только данного сигнала, но не исключено. Поэтому на всякий случай лучше все же писать так. Как минимум в любом случае одной обработки сигналов достаточно, и лучше эту обработку писать как можне раньше. Практически в самом начале скрипта.
|
Автор: fray 4.9.2007, 09:56 |
Ну по мне это не приемлимая прога, так как она просто создает потомков, и какждму дает следующую ссылку(увеличивая счетчик), обмена между процессами нет. Поэтому это как-то не интересно ![]() А зачем вообще через сигнал $SIG{CHLD} начинать ждать завершения процесса, может просто установить в родиделе wait() ? |
Автор: Bulat 4.9.2007, 11:26 | ||
fray, при форке как правило обмена нет, правда можно пользоватся пайпами или через запись в файл, но в таких случаях лучше уж чем-то другим, так проще. Кроме того зачастую совсем необязательно обратно что-то возвращять. При распарсивании сайтов(сбор ссылок и инфы), чем я сейчас занимаюсь, этого вполне достаточно, дочернему процессц вполне достаточно передать ссылку, так как конечные результаты будут в базе. Т.е. нам совсем не обязательно что-то еще возвращять. Дочерный процесс сам все сделает, занесет данные в базу... ![]()
Читай про "зомби" |
Автор: fray 5.9.2007, 12:27 | ||||
А счего у тебя зомби образуются я просто делаю waitpid $_,0 for @pids; и никаких зомби, что там у тебя дедлок возникает ? |
Автор: Bulat 9.9.2007, 11:29 |
fray, Почему образуются зомби не могу сказать конкретно, не читал хороших статей на эту тему. Кроме того у меня есть сроки, я решил эту проблему таким образом, решил грамотно, и код замечательно работает - значит стал на еще один шаг ближе к окончанию проекта. Будет время разберусь. А сипользовать обработку сигналов, лично для меня удобнее, ибо в целом можно установить некий уровень защиты, при обработке сигналов типа kill и т.п., мало ли сисадмин ошибется и убъет мой проц, когда еще тот не доработает ![]() ![]() |
Автор: G0rinich 2.10.2007, 10:35 |
Для сетевой многозадачности используйте POE и не парьтесь ;) Почему, можно прочитать у меня http://gorinich.net/posts/12. Если будут вопросы, с удовольствием отвечу. Если работа не связана с сетью, а представляет собой просто обработку данных, то при использовании подобной многозадачности вы скорее потеряете ;) Добавлено через 32 секунды подписку забыл включить ![]() |
Автор: Bulat 3.10.2007, 09:24 |
G0rinich, то что ты предлагаешь не всегда есть гуд... Порой инструменты, которыми приходится пользоватся немного ограничены.... Изначально вообще хотел многопоточность реализовать через треды и нити, но, как мне потом сказали, не на всех серверах перл это поддерживает и т.п., вообщем сказали пиши код так, чтобы он мог работать везде ![]() Да я не думаю, что можно особо что-то потерять... Вообще я сейчас для очередного проекта, хочу заюзать некоторые принципы ООП, даже темку тут уже завел, при таком подходе к данным не думаю, что от остального кода уже будет многое зависить ![]() |
Автор: G0rinich 3.10.2007, 10:11 |
Bulat, ну так POE работает везде ;) Прикручиваешь модуль и все работает. Проверено. Плюс скорость разработки + отсутствие много гемора по организации многозадачности (за тебя это уже сделали) + еще много плюсов. Из пауков написанных на POE я выжимал 100-1000 запросов в секунду. Разгонялся до 20 Мбит/сек. Дальше пропускная способность DNS не давала :( И это все одним процессом ;) |
Автор: Nab 3.10.2007, 14:02 |
Bulat, слушай его, он дело говорит ![]() |
Автор: Bulat 4.10.2007, 15:55 |
G0rinich, Nab, Я раз пять начальнику писал, что с той базой, которую он мне выделил работать не возможно, там запросы самые тривиальные иногда всинут по несколько минут.... Была б моя воля, е вообще писал бы на ООП, но низя, хотя вот сейчас все равно впихиваю... Или вот еще примерчик, когда делал языковую локализацию, у меня изначально было два варианта: динамический, или хранить переводы в базе... И я склоянлся к базе... И лишь когда при динамическом переводе стала неустраивать скорость загрузки интерфейса, пришлось вернутся к варианту с базой, и переделывать хорошую часть кода. ![]() |
Автор: G0rinich 6.10.2007, 17:55 |
POE - это не совсем ООП ;) Некоторые принципы конечно есть. А вот насчет кроссплатформенности там все очень хорошо, но лучше себя чувствует под никсами. Кстати, про виснущий запрос можно будет забыть, он никак не затормозит работы ;) |
Автор: fray 8.10.2007, 22:22 |
Быстрые многопоточные проги к сожалению на перле не напишешь. |