LINUX.ORG.RU

perl fork не паралелится


0

0

вот такая програмулина, суть которой в том, что надо параллельно 
дернуть 10 сайтов с яндеха. Но оно не дергает параллельно =( 

че я делаю не так? =(

[user@server generator]$ cat y.pl
#!/usr/bin/perl -w

use strict;
use LWP::Simple;

my (@child,$txt,$n,$string,%h,$c,%h1);

my $t="http://www.yandex.ru/yandsearch?stype=www&nl=0&text=10000";
;
$txt=get($t);
foreach $n (2 .. 11){
  $c++;
  if($txt=~m!a tabindex="$n" onclick=.*?href="(.*?)"!igs){
    $h{$c}=$1 if $1;
  }
}

&forks();
undef %h;
$c = 0;

sub forks{
  for(1..10) {
    my $pid = fork();
    if($pid) {
      push @child, $pid;
      print "$pid $h{$_}\n";
      my $txt1=get($h{$_});
      print "[========> done <========]\n";
    } else {
      exit;
    }
  }
  for(@child) {
    waitpid($_,0);
  }
}

print "ok\n";

** Joe's Own Editor v2.9.5 ** Copyright (C) 2001 **
File y.pl not changed so no update needed.
[user@server generator]$ perl y.pl


1311 http://10000sites.org/
[========> done <========]
1312 http://teren.lutsk.ua/
[========> done <========]
1313 http://www.oglibrary.ru/
[========> done <========]
1315 http://www.cddoma.com.ua/51/46303/10000_Photos_vol_1/
[========> done <========]
1316 http://www.cddoma.lviv.ua/51/46303/10000_Photos_vol_1/
[========> done <========]
1317 http://www.forexinvest.ru/kapital1.html
[========> done <========]
1318 http://www.whitegoods.ru/goods/9505.htm
[========> done <========]
1319 http://www.compulenta.ru/165589/
[========> done <========]
1320 http://www.m3x.ru/shop.asp?pid=72735
[========> done <========]
1321 http://www.centrmag.ru/book1121195.html
[========> done <========]
ok

по идее оно должно породить 10 процессов, которые параллельно дернут 
10 ссылок из яндеха по ключевому слову чтобы не ждать последовательно,
 что гораздо медленнее... но оно работает почему-то последовательно. 
Мож я чето не понял??
☆☆

еслиб оно работало истинно паралельно. то не было бы монотонно возрастающей последовательности нуумерации пидов в начале каждой строки с урлом: 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 ... оно должно этот чортов пид выводить тогда, когда произойдет запрос к сайту, т.е. в случайном порядке, оное зависит от скорости коннекта, а так получается что прога работает, хотя и с форком, но как будто последовательный перебор...

vilfred ☆☆
() автор топика
Ответ на: комментарий от vilfred

Наскка я понимаю, то если $pid не 0, то ты в родителе и как раз в нём надо продолжать цикл, а не лезть на сайт. а так получается, что твой родитель последовательно форкает себя 10 раз, каждый раз лезет на сайт, а дети просто делают exit().

По-моему, так...

yz
()

Конечно. У тебя всю работу делает родитель, потому и получается последовательно. 

Переделай функцию forks():

sub forks{
  for(1..10) {
    my $pid = fork();
    if($pid) {
      push @child, $pid;            
    } 
    else {      
      my $txt1=get($h{$_});
      print "$$  $h{$_}\n";
      print "[========> done <========]\n";
      exit;
    }
  }
  for(@child) {
    waitpid($_,0);
  }
}

Hjorn
()
Ответ на: комментарий от Hjorn

Хотя так тоже не совсем правильно. Лучше объединить два вызова print в один, иначе получается race condition. Впрочем, в данной случае это не так важно.

Hjorn
()

Как прально сказал yz ты родителем делал get, а потомком просто exit.
Насчет пидов ты не прав, в коде пид печатается сразу после форка, так что линейная зависимость номеров - это нормально в данном случае. А вот ==done== печатается действительно после реальной закачки.
Вот как должно выглядеть.

#!/usr/bin/perl -w

use strict;
use LWP::Simple;

my (@child,$txt,$n,$string,%h,$c,%h1);

my $t="http://www.yandex.ru/yandsearch?stype=www&nl=0&text=10000";
;

$txt=get($t);
foreach $n (2 .. 11){
  $c++;
    if($txt=~m!a tabindex="$n" onclick=.*?href="(.*?)"!igs){
        $h{$c}=$1 if $1;
    }
}

&forks();
undef %h;
$c = 0;

sub forks{
    for(1..10) {
        my $pid = fork();
	if($pid) {
    	    push @child, $pid;
            print "$pid $h{$_}\n";
        } else {
	    my $txt1=get($h{$_});
            print "[========> done <========]\n";
    	    exit;
        }
    }
  for(@child) {
      waitpid($_,0);
  }
}
print "ok\n";

wellcomer
()
Ответ на: комментарий от cobold

да уже клинка ваще пошла, файл правлю на одном сервере, а запускаю на другом и фтыкаю долго, почему изменения не видны... пепец, спать пора

vilfred ☆☆
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.