Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Thread::Queue


Автор: Guran 13.10.2011, 10:50
Добрый день. У меня возникла небольшая проблема с Thread::Queue, я не понимаю как это вообще применить. Понятного мне мануала не нашел. Может кто-нибудь может дать ссылку на подробные объяснения "на пальцах", или написать, как применять это для создания очередей тредов? (Когда тредов N а они запускаются группами по N\10)

Автор: arto 13.10.2011, 13:17
Thread::Queue -- для безопасной работы с очередями в thread-окружении.
посмотрите Thread::Pool

Автор: Guran 13.10.2011, 16:44
Количество запросов постоянно меняется, от 500 до 3,5к так что максимальное для пула указать сложно. А с Queue непонятно как сделать так, чтобы при выводе не происходило ошибки из-за того, что последняя группа не 30 запросов, а, например, 17

Автор: Pfailed 13.10.2011, 18:10
Цитата(Guran @  13.10.2011,  16:44 Найти цитируемый пост)
Количество запросов 

Что за запросы?

Автор: DurRandir 14.10.2011, 11:42
<telepate on>граббинг http с потоками, да?)</telepate off>

Автор: Guran 16.10.2011, 14:06
Вот такой код получился, но считает он все равно по 1 запросу, как будто тредов и нет. подскажите, где я ошибся?

Код

#!/usr/bin/perl

use threads;
use strict;
use Switch;
use Net::SNMP;
use Thread::Queue;
use DBI;

my $b_ip : shared;
my $b_oid : shared;
my @mas_ip : shared;
my @mas_id_mod : shared;
my @users=0..31;
my @thread;
my @globx : shared;

my $dbh = DBI->connect("DBI:Pg:dbname=postgres;host=host",
"login", "passwd") || die $DBI::errstr;

my $query = "SELECT switch_map.switch_place2.ip_address, switch_map.models.id 
FROM switch_map.switch_place2, switch_map.sw_warehouse, switch_map.models
WHERE (switch_map.switch_place2.sw_id = switch_map.sw_warehouse.id) AND (switch_map.sw_warehouse.model_id = switch_map.models.id) AND
(switch_map.models.id IN (1,2,3,7,15));";

my $output = $dbh->prepare($query);
$output->execute;
my ($b_ip, $id_mod);
$output->bind_columns(undef, \($b_ip, $id_mod));

while ($output->fetch) {
    push @mas_ip, $b_ip;
    push @mas_id_mod, $id_mod;
}

for (my $j=0; $j<$#mas_ip; $j++){
    foreach(@users) {
        if ($j<$#mas_ip){
            switch($mas_id_mod[$j]){
                case 1 {$b_oid = "1.3.6.1.4.1.171.11.64.1.2.10.5.1.4";}
                case 2 {$b_oid = "1.3.6.1.4.1.171.11.63.6.2.7.11.1.4";}
                case 3 {$b_oid = "1.3.6.1.4.1.171.11.63.3.2.7.5.1.4";}
                case 7 {$b_oid = "1.3.6.1.4.1.171.11.63.6.2.7.11.1.4";}
                case 15 {$b_oid = "1.3.6.1.4.1.171.12.73.3.1.3.1.2";}
            }
            $b_ip = $mas_ip[$j];
            $globx[$_] = Thread::Queue->new;
            $thread[$_] = threads->create(\&kar, $b_ip, $b_oid)->join;
            $j++;
        }
    }

    foreach (@users){
        if ($j<$#mas_ip){
            switch($mas_id_mod[$j]){
                case 1 {$b_oid = "1.3.6.1.4.1.171.11.64.1.2.10.5.1.4";}
                case 2 {$b_oid = "1.3.6.1.4.1.171.11.63.6.2.7.11.1.4";}
                case 3 {$b_oid = "1.3.6.1.4.1.171.11.63.3.2.7.5.1.4";}
                case 7 {$b_oid = "1.3.6.1.4.1.171.11.63.6.2.7.11.1.4";}
                case 15 {$b_oid = "1.3.6.1.4.1.171.12.73.3.1.3.1.2";}
            }
            $b_ip = $mas_ip[$j];
            if ($globx[$_]->pending eq 0) {
                $globx[$_]->enqueue(-1);
                $thread[$_] = threads->create(\&kar, $b_ip, $b_oid)->join;
                $j++;
            }
        }
    }
}

sub kar
{
# Тут расположена сама функция, треды в ней не участвуют
}

Автор: Guran 17.10.2011, 11:02
В конце концов получилась такая штука, может кому поможет:
Код

#!/usr/bin/perl

use threads;
use strict;
use Switch;
use Net::SNMP;
use Thread::Queue;
use DBI;

my $b_ip : shared;
my $b_oid : shared;
my @mas_ip : shared;
my @mas_id_mod : shared;
my @users=0..9;
my %thread;
my %globx : shared;
my $quglb : shared;
my $j : shared = 0;

my $dbh = DBI->connect("DBI:Pg:dbname=postgres;host=host",
"login", "passwd") || die $DBI::errstr;

my $query = "SELECT switch_map.switch_place2.ip_address, switch_map.models.id 
FROM switch_map.switch_place2, switch_map.sw_warehouse, switch_map.models
WHERE (switch_map.switch_place2.sw_id = switch_map.sw_warehouse.id) AND (switch_map.sw_warehouse.model_id = switch_map.models.id) AND
(switch_map.models.id IN (1,2,3,7,15));";

my $output = $dbh->prepare($query);
$output->execute;
my ($b_ip, $id_mod);
$output->bind_columns(undef, \($b_ip, $id_mod));

while ($output->fetch) {
    push @mas_ip, $b_ip;
    push @mas_id_mod, $id_mod;
}

$dbh->disconnect;

foreach(@users) {
    if ($j<$#mas_ip){
        switch($mas_id_mod[$j]){
                case 1 {$b_oid = "1.3.6.1.4.1.171.11.64.1.2.10.5.1.4";}
                case 2 {$b_oid = "1.3.6.1.4.1.171.11.63.6.2.7.11.1.4";}
                case 3 {$b_oid = "1.3.6.1.4.1.171.11.63.3.2.7.5.1.4";}
                case 7 {$b_oid = "1.3.6.1.4.1.171.11.63.6.2.7.11.1.4";}
                case 15 {$b_oid = "1.3.6.1.4.1.171.12.73.3.1.3.1.2";}
        }
        $b_ip = $mas_ip[$j];
        $globx{$_} = Thread::Queue->new;
        $thread{$_} = threads->create(\&kar, $b_ip, $b_oid);
        $j++;
    }
}


while ($j<$#mas_ip){
    foreach (@users){
        if ($j<$#mas_ip) {
             if ($globx{$_}->pending eq 0) {
                switch($mas_id_mod[$j]){
                    case 1 {$b_oid = "1.3.6.1.4.1.171.11.64.1.2.10.5.1.4";}
                    case 2 {$b_oid = "1.3.6.1.4.1.171.11.63.6.2.7.11.1.4";}
                    case 3 {$b_oid = "1.3.6.1.4.1.171.11.63.3.2.7.5.1.4";}
                    case 7 {$b_oid = "1.3.6.1.4.1.171.11.63.6.2.7.11.1.4";}
                    case 15 {$b_oid = "1.3.6.1.4.1.171.12.73.3.1.3.1.2";}
                }
                $globx{$_}->enqueue($j);
                $j++;
            }
        }
    }
}
=head
my $f=1;
while ($f>0) {
    $f=0;
    foreach(@users) {
        if ($globx{$_}->pending eq 0) {
        } else {
            $f=1;
        }
    }
}
=cut
sleep(2);
foreach(@users) {

    $thread{$_}->detach;
}

sub kar
{
while (my $w = $globx{$_}->dequeue){
if ($w>0) {
======Код функции исполняемой нитями
}

Автор: taryk 17.10.2011, 16:38
Цитата(Guran @  17.10.2011,  10:02 Найти цитируемый пост)
В конце концов получилась такая штука, может кому поможет:


чтобы юзать shared переменные нужно добавить 
Код

use threads::shared;

Автор: Guran 23.10.2011, 05:12
Нашел несколько косяков в коде. Рабочий вариант:

Код

#!/usr/bin/perl

use threads;
use strict;
use Switch;
use Net::SNMP;
use Thread::Queue;
use threads::shared;
use DBI;

my $b_ip : shared;
my $b_oid : shared;
my @mas_ip : shared;
my @mas_id_mod : shared;
my @mas_id_ip : shared;
my @users=0..29;
my %thread;
my %globx : shared;
my $j : shared = 0;
my @sql : shared;


foreach(@users) {
    if ($j<$#mas_ip){
        $globx{$_} = Thread::Queue->new;
        $thread{$_} = threads->create(\&kar);
        $j++;
    }
}

$j=0;
while ($j<$#mas_ip){
    my $f=0;
    foreach (@users){
        if ($j<$#mas_ip) {
             if ($globx{$_}->pending eq 0) {
                $globx{$_}->enqueue($j);
                $j++;
            }
        }
    }
}

sleep(3);
foreach(@users) {
    if ($globx{$_}->pending eq 0) {
        $globx{$_}->enqueue(-1);
        $thread{$_}->join;
    }
}

sub kar
{
    while (my $w = $globx{$_}->dequeue){
       if ($w<0) { return "ok";
       }else{
#===============Тут нужная вам функция

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)