Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Многопоточность LWP как? Ну извините не доходит 
:(
    Опции темы
Riddick
  Дата 25.6.2007, 21:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 24.6.2007

Репутация: нет
Всего: нет



Прочитал про форки, но никак не пойму как применить. Понятно что многое об этом написано, но никак не дойдет до меня. Если не трудно, прошу Уважаемых Гуру помочь, новичку самоучке smile .
Из кода ниже станет ясен алгоритм выполнения скрипта, а вот как сделать его многопоточным надеюсь найти ответ здесь на форуме.
Код

#открываю исходный файл, каждая строчка которого содержит определенный параметр

     open (CC, '<temp/temp1.txt');
          @col=<CC>;
             $col=@col;
     close (CC);

#Запускаю цикл построчного чтения файла. Каждая строка является запросом (грубо говоря урлом)

$i=1;
     while ($i <= $col){

#в нижеследующией переменной содержится ответ сервера, а точнее html страница

     my $html = Geturll($url);

#здесь идет блок получения вышеуказанной переменной $html

sub Geturll {
    my $url = shift;
    my $ua = LWP::UserAgent->new;
    my $response = $ua->get($url);
    if ($response->is_success and $response->status_line =~ /200/ ) {
        return $response->content;
    } else {
        Geturl($url);
    }
}

#Дальше идет обработка полученной переменной $html


foreach (split /\n/, $html) {

 if ($html=~ m/\&nbsp\;(\d+)/g)
 {$chislo = $1;

if ($chislo < $miniz){last();}

}

if ($html=~ m/color=#000000>([A-Za-z\s\d\.]+)/g)
 {$dannye = $1;

if ($dannye eq ""){last();}

}
#Запись полученных данных в файл
open (CC, 'text.txt');
print CC "$dannye\n";
close (CC);

}
$i++;
}

#Ну и дальше сообщение что все закончилось

print <<EOF;

Поздравляю, ты наконец то дождался!

EOF



Из кода понятно, что скрипт по очереди выбирает по одному запросу из фала и обрабатывает и ждать приходится "от забора и до обеда", а вот если бы он это делал многопоточно, ну хотябы в 30 или 50, то время ожидание сократилось бы в разы. Буду очень благодарен за помощь.
З.Ы. Сильно не бейте, если очень туплю!
PM MAIL   Вверх
Ivan Kolesnikov
Дата 26.6.2007, 06:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 9.3.2005
Где: г. Новокузнецк

Репутация: нет
Всего: 6



В Perl существует, по крайней мере, два способа организации многопоточности, это fork и собственно потоки.

Я работал только с fork, поэтому расскажу про него: когда ты делаешь системный вызов fork, то создается копия твоего процесса, при этом родительскому процессу возвращается pid только что созданного нового процесса, а дочернему процессу - ноль.

В твоем случае можно многопоточность реализовать следующим образом:
Код

#открываю исходный файл, каждая строчка которого содержит определенный параметр

open (CC, '<temp/temp1.txt');
@col=<CC>;
$col=@col;
close (CC);

#Число потоков
$COUNT_THREAD = 20;

#Создаем потоки

for ($i = 0; $i<$COUNT_THREAD; $i++) {
    $pid = fork();
    if ($pid) {
        #Это родитель
        #Будем сохранять pid-ы потоков, чтобы потом дождаться их всех завершения
        push @pids, $pid;
    } else {
        #А это уже новый поток
        for ($j = $i; $j<$col; $j+=$COUNT_THREAD) {
            my $html = Geturll($url);
            foreach (split /\n/, $html) {
                if ($html=~ m/\&nbsp\;(\d+)/g) {
                    $chislo = $1;
                    if ($chislo < $miniz){
                        last();
                    }
            }
            if ($html=~ m/color=#000000>([A-Za-z\s\d\.]+)/g) {
                $dannye = $1;
                if ($dannye eq ""){
                    last();
                }
            }
            #Запись полученных данных в файл
            open (CC, 'text.txt');
            print CC "$dannye\n";
            close (CC);
        };
    };
};

#Потоки запущены ждем их завершения
waitpid($_) foreach @pids;

#Ну и дальше сообщение что все закончилось

print <<EOF;

Поздравляю, ты наконец то дождался!

eof

#здесь идет блок получения вышеуказанной переменной $html

sub Geturll {
    my $url = shift;
    my $ua = LWP::UserAgent->new;
    my $response = $ua->get($url);
    if ($response->is_success and $response->status_line =~ /200/ ) {
        return $response->content;
    } else {
        Geturl($url);
    }
}


Я чуток подправил код, чтобы проще было читать, да я его не проверял, так что могут быть небольшие ошибки.

Но суть в следующем основной поток создает необходимое число потоков, каждый из которых знает какие данные ему необходимо обработать (он обрабатывает не все подрят, а скачет (величина прыжка равна количеству потоков). При этом основной поток сохраняет идентификаторы своих детей, чтобы в конце подождать пока они все завершаться...

Если что не понятно пиши...
--------------------
PM MAIL ICQ   Вверх
dimes
Дата 26.6.2007, 08:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 249
Регистрация: 20.7.2004
Где: то около СПБ

Репутация: нет
Всего: 14



Riddick, 
Очень много ошибок в коде.


Код

open (CC, '<temp/temp1.txt');
@col=<CC>;
$col=@col;
close (CC);


Каждый элемент @col будут заканчиваться "\n" а то и "\r\n"
Это может быть принципиально.

насчет этого: $col=@col;
В perl много способов как пройтись по массиву
Код

for( my $_i=0;$_i<@col;$_i++ ){
 my $_url=$col[$_i];



Код

for( my $_i=0;$_i<=$#col;$_i++ ){
 my $_url=$col[$_i];



Код

for( @col ){
 my $_url=$_;


и т.д.

Функция "Geturll" объявляется прямо в цикле, это все равно что грязными руками лапать прекрасное и вечное  smile

Код

#Запись полученных данных в файл
open (CC, 'text.txt');
print CC "$dannye\n";
close (CC);

-Это не запись а чтение
-не хватает обработчика ошибок open (CC, 'text.txt') or &my_prc_err($!);
-нет flock (в примере Ivan Kolesnikov это особенно важно)

НЕТ "use strict;"
пока не научился вставлять
use strict;
use CGI::Carp qw (fatalsToBrowser);
ты далеко не продвинешься.
еще бы хорошо -w (use warning;)

Код

if ($response->is_success and $response->status_line =~ /200/ ) {
 return $response->content;
} else {
  Geturl($url);
}

Если на той стороне что то мега ляжет или изменится у тебя зависнут скрипты, бесконечные рекурсии не самое правильно решение особенно у тебя  smile 

PM ICQ   Вверх
amg
Дата 26.6.2007, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 1
Всего: 50



Riddick, вот этот кусок твоего кода, боюсь, делает не (совсем) то, что ты хочешь. Можно долго рассказывать, что в нем нехорошо, но проще поправить. Только я, к сожалению, не понял, чего нужно добиться.
Код

foreach (split /\n/, $html) {
  if ($html=~ m/\&nbsp\;(\d+)/g) {
    $chislo = $1;
    if ($chislo < $miniz) {last();}
  }
  if ($html=~ m/color=#000000>([A-Za-z\s\d\.]+)/g) {
    $dannye = $1;
    if ($dannye eq "") {last();}
  }
  open (CC, 'text.txt');
  print CC "$dannye\n";
  close (CC);
}

PM MAIL   Вверх
JAPH
Дата 26.6.2007, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 8.1.2007
Где: Ленобласть

Репутация: 1
Всего: 23



Где-то я натыкался на то, что нельзя давать детям выходить обратно в родительский код. То есть после кода, выделенного amg, не нужен exit? И, кстати, eof в нижнем регистре после <<EOF - опечатка?


--------------------
Что непонятно - спрашиваем smile
PM MAIL ICQ   Вверх
Ivan Kolesnikov
Дата 26.6.2007, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 9.3.2005
Где: г. Новокузнецк

Репутация: нет
Всего: 6



Цитата

Где-то я натыкался на то, что нельзя давать детям выходить обратно в родительский код. То есть после кода, выделенного amg, не нужен exit? И, кстати, eof в нижнем регистре после <<EOF - опечатка? 

да конечно нужен exit и на счет eof - опечатка. Просто писал сразу в браузере и не проверял работу...
--------------------
PM MAIL ICQ   Вверх
Riddick
Дата 26.6.2007, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 24.6.2007

Репутация: нет
Всего: нет



Большое спасибо всем, все учту и приму к сведению. Насчет ошибок в коде, тоже спасибо, хотя вроде копипастом вставлял а потом правил, поэтому и ошибки. Насчет use strict - говорили же мне сразу привыкать сразу его юзать, теперь точно начну, насчет фатал браузер и варнингов вставляю в каждый скрипт.
Еще раз всем спасибо, если возникнут вопросы, хоть знаю куда теперь обратиться. Всем респект.
PM MAIL   Вверх
Riddick
Дата 26.6.2007, 18:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 24.6.2007

Репутация: нет
Всего: нет



Попробовал, браузер выдал кучу ошибок
Not enough arguments for waitpid at d:\cgi-bin\PARSER~1\parser2.cgi line 72, near "$_) "

Missing right curly or square bracket at d:\cgi-bin\PARSER~1\parser2.cgi line 83, at end of line
  (Might be a runaway multi-line << string starting on line 77)

Ну и еще, сечас проверяю, может опять я ступил
PM MAIL   Вверх
igor_k75
Дата 27.6.2007, 22:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 27.6.2007

Репутация: нет
Всего: нет



Можно обойтись и без fork.

LWP::Parallel - http://search.cpan.org/~marclang/ParallelU...LWP/Parallel.pm
PM MAIL   Вверх
nitr
Дата 27.6.2007, 22:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

Репутация: 12
Всего: 84



igor_k75, вы сразу приведите пример его использования smile Поймёте, что многим людям проще с форками работать, или (что сам бы посоветовал) с POE разобраться!

;)

Это сообщение отредактировал(а) nitr - 27.6.2007, 22:48


--------------------
PM   Вверх
Riddick
Дата 28.6.2007, 05:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 24.6.2007

Репутация: нет
Всего: нет



Если не секрет, что такое РОЕ и где про него почитать. А так сделал на форках, в 20 потоков проц грузится на 98%, может из-за того, что Апачи стоит на Windows, потому как прочитал, форки это линуксовая стихия.
PM MAIL   Вверх
sharq
Дата 28.6.2007, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Perl Liker
**


Профиль
Группа: Участник
Сообщений: 841
Регистрация: 13.12.2004
Где: Ростов-на-Дону

Репутация: 2
Всего: 28



Riddick, 

http://search.cpan.org/%7Ercaputo/POE/
http://poe.perl.org/
http://perl.wikia.com/wiki/POE

На русском информации очень мало, пока это только обсуждения здесь на форуме и в блогах.

 smile 


--------------------
[color=gray]There's More Than One Way To Do It[/color]
PM MAIL WWW ICQ Skype   Вверх
Riddick
Дата 2.7.2007, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 24.6.2007

Репутация: нет
Всего: нет



Опять вопрос, для тех кто работает с форками и на денвере. Можно ли как нибудь уменьшить нагрузку на проц при применении Forkов, если можно напишите плиз, если нет то может можно реализовать как нибудь по другому многопоточность на стандартных модулях. Заранее спасибо!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl: CGI программирование"
korob2001
sharq
  • В этом разделе обсуждаются вопросы относящиеся только к CGI программированию
  • Если ваш вопрос не относится к системному или CGI программированию, задавайте его в общем разделе
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", качать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: разработка для Web | Следующая тема »


 




[ Время генерации скрипта: 0.0610 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.