2013-05-01 4 views
0

특정 길이 (테스트 용 5)의 새로운 다차원 배열을 만들고 값으로 채운 다음 해당 배열을 서브 루틴으로 전달하려고합니다. 주 코드가 다음 값을 채울 새 배열을 계속 작성할 수 있도록 주 코드와 별도의 스레드에서 실행됩니다. 이 사이클은 끊임없이 계속되어야합니다.Perl - 새 배열을 만들고 서브 루틴 스레드에 전달합니다.

배열이 전달 된 것을보고 $set[0]에 대한 값을 볼 수 있지만 배열이 덮어 쓰기 된 것처럼 보입니다. 나는 여기서 무슨 일이 일어나고 있는지 잘 모르겠습니다. 하이퍼 링크 연결 개체가 제대로 전달되지 않습니다. 각 스레드에 새 연결 개체를 만들어야했습니다. 내가 여기서 무엇을 놓치고 있니?

#!/usr/bin/perl -w -I /opt/hypertable/0.9.7.3/lib/perl -I /opt/hypertable/0.9.7.3/lib/perl/gen-perl 
use strict; 
use IO::Socket; 
use Geo::IP; 
use threads qw(stringify); 
use Net::NBName; 
use Data::Dumper; 
use Hypertable::ThriftClient; 

my $hypertable = new Hypertable::ThriftClient("Server", 38080); 
my $namespace = $hypertable->namespace_open("TEST"); 
my $MAXLEN  = 1524; 
my $buf  = ''; 

my $limit = 5; #length of array 
my $sock = IO::Socket::INET->new(LocalPort => '514', Proto => 'udp') || die("Socket: [email protected]"); 

do { 
    my $count = 0; 
    my @set; 

    for ($count = 0; $count <= $limit; $count++) { 
     $sock->recv($buf, $MAXLEN); 
     my ($port, $ipaddr) = sockaddr_in($sock->peername); 
     my $hn = gethostbyaddr($ipaddr, AF_INET); 
     $buf =~ /<(\d+)>(.*?):(.*)/; 
     my $msg = $3; 
     $set[$count][0] = $hn; 
     $set[$count][1] = $msg; 
     print $count. " --> " 
      . $set[$count][0] . " --> " 
      . $set[$count][1] 
      . "\n"; #Multi dimensional array 

    } 

    my $thr = threads->create('logsys', @set, $hypertable); 

} while (1); 


sub logsys { 

    my $count = 0; 

    for ($count = 0; $count <= $limit; $count++) { 
     my $hypertable = shift; # Here I want to use the single NoSQL db connector object for all threads 
     my @set = shift; 

     print $count. " --> " 
      . @set->[$count][0] . " --> " 
      . @set->[$count][1] 
      . "\n"; # Here I expect the same exact array elements 

     #DO SOME MORE STUFF here 
    } 
} 

편집 : 간단한 코드 중 하나 스레드 또는 스레드없이 실행합니다. 스레드에서 실행될 때 처리는 배열의 모든 요소를 ​​처리하지 않습니다. 그러나 스레딩없이 실행하면 모든 요소가 처리됩니다.

#!/usr/bin/perl -w -I /opt/hypertable/0.9.7.3/lib/perl -I /opt/hypertable/0.9.7.3/lib/perl/gen-perl 
use strict; 
use IO::Socket; 
use Geo::IP; 
use threads qw(stringify); 
use Net::NBName; 
use Data::Dumper; 
use Hypertable::ThriftClient; 

# Syslog Variables and Constants 
my $MAXLEN = 1524; 
my $limit = 5; #for testing 
my $sock; 
# Start Listening on UDP port 514 
$sock = IO::Socket::INET->new(LocalPort => '514', Proto => 'udp') || die("Socket: [email protected]"); 

my $buf = ''; 
    my $count = 0; 
    my @set; 

    for ($count = 0; $count <= $limit; $count++) { 
    $sock->recv($buf, $MAXLEN); 
    my ($port, $ipaddr) = sockaddr_in($sock->peername); 
    my $hn = gethostbyaddr($ipaddr, AF_INET); 
    $buf=~/<(\d+)>(.*?):(.*)/; 
    my $msg=$3; 
    $set[$count][0] = $hn; 
    $set[$count][1] = $msg; 
print $count." --> ".$set[$count][0]." --> ".$set[$count][1]."\n";#Print original array, should print 5 elements 

    my $thr = threads->create('logsys',@set); 

#&logsys(@set); 

sub logsys { 
my $count = 0; 
my @set= @_; 

print "--------------------- ".scalar (@set)." -------------------\n"; 

for ($count=0; $count <= $limit; $count++) { 
print $count." --> ".$set[$count][0]." --> ".$set[$count][1]."\n";#print passed array, should same exact 5 elements 
if (open(WW,">syslog")){print WW $count." --> ".$set[$count][0]." --> ".$set[$count][1]."\n"; close(WW);} 

} 
} 

O/P 스레드로 실행하면

0 --> ids-01p --> 23:48 IDS01 SFIMS: [FLIDS][Enterprise][138:4:1] sensitive_data: sensitive data - U.S. social security numbers without dashes [Classification: Sensitive Data] [Priority: 2] {TCP} 10.10.97.42:3065 -> 33.87.66.38:80 
1 --> ids-01p --> 23:50 IDS01 SFIMS: [FLIDS][Enterprise][138:4:1] sensitive_data: sensitive data - U.S. social security numbers without dashes [Classification: Sensitive Data] [Priority: 2] {TCP} 10.10.1.254:26616 -> 78.67.61.202:80 
2 --> ids-01p --> 23:50 IDS01 SFIMS: [FLIDS][Enterprise][138:4:1] sensitive_data: sensitive data - U.S. social security numbers without dashes [Classification: Sensitive Data] [Priority: 2] {TCP} 10.10.1.254:39180 -> 56.164.27.51:80 
3 --> ids-01p --> 23:51 IDS01 SFIMS: [FLIDS][Enterprise][138:4:1] sensitive_data: sensitive data - U.S. social security numbers without dashes [Classification: Sensitive Data] [Priority: 2] {TCP} 10.10.52.97:53967 -> 173.194.37.97:80 
4 --> ids-01p --> 23:51 IDS01 SFIMS: [FLIDS][Enterprise][119:15:1] http_inspect: OVERSIZE REQUEST-URI DIRECTORY [Classification: Potentially Bad Traffic] [Priority: 2] {TCP} 10.190.1.254:57265 -> 34.44.17.21:80 
5 --> ids-01p --> 23:51 IDS01 SFIMS: [FLIDS][Enterprise][119:15:1] http_inspect: OVERSIZE REQUEST-URI DIRECTORY [Classification: Potentially Bad Traffic] [Priority: 2] {TCP} 10.190.1.254:41960 -> 34.44.17.29:80 
--------------------- 6 ------------------- 
0 --> ids-01p --> 23:48 IDS01 SFIMS: [FLIDS][Enterprise][138:4:1] sensitive_data: sensitive data - U.S. social security numbers without dashes [Classification: Sensitive Data] [Priority: 2] {TCP} 10.190.97.42:3065 -> 43.87.66.38:80 
Perl exited with active threads: 
     1 running and unjoined 
     0 finished and unjoined 
     0 running and detached 
1 --> ids-01p --> 23:50 IDS01 SFIMS: [FLIDS][Enterprise][138:4:1] sensitive_data: sensitive data - U.S. social security numbers without dashes [Classification: Sensitive Data] [Priority: 2] {TCP} 10.190.1.254:26616 -> 43.67.61.202:80 

스레드없이 실행으로 O/P :

0 --> ids-01p --> 36:48 IDS01 SFIMS: [FLIDS][Enterprise][138:4:1] sensitive_data: sensitive data - U.S. social security numbers without dashes [Classification: Sensitive Data] [Priority: 2] {TCP} 10.10.1.254:34053 -> 69.164.26.77:80 
1 --> ids-01p --> 36:50 IDS01 SFIMS: [FLIDS][Enterprise][138:4:1] sensitive_data: sensitive data - U.S. social security numbers without dashes [Classification: Sensitive Data] [Priority: 2] {TCP} 10.1.65.51:57977 -> 216.137.41.5:80 
2 --> ids-01p --> 36:53 IDS01 SFIMS: [FLIDS][Enterprise][128:4:1] ssh: Protocol mismatch [Classification: Detection of a Non-Standard Protocol or Event] [Priority: 2] {TCP} 10.10.241.46:11120 -> 10.10.125.227:22 
3 --> ids-01p --> 36:54 IDS01 SFIMS: [FLIDS][Enterprise][128:4:1] ssh: Protocol mismatch [Classification: Detection of a Non-Standard Protocol or Event] [Priority: 2] {TCP} 10.10.241.46:11122 -> 10.1.125.225:22 
4 --> ids-01p --> 36:54 IDS01 SFIMS: [FLIDS][Enterprise][138:4:1] sensitive_data: sensitive data - U.S. social security numbers without dashes [Classification: Sensitive Data] [Priority: 2] {TCP} 10.1.118.96:61686 -> 50.19.254.195:80 
5 --> ids-01p --> 36:54 IDS01 SFIMS: [FLIDS][Enterprise][138:4:1] sensitive_data: sensitive data - U.S. social security numbers without dashes [Classification: Sensitive Data] [Priority: 2] {TCP} 10.1.1.254:29437 -> 184.73.178.248:80 
--------------------- 7 ------------------- 
0 --> ids-01p --> 36:48 IDS01 SFIMS: [FLIDS][Enterprise][138:4:1] sensitive_data: sensitive data - U.S. social security numbers without dashes [Classification: Sensitive Data] [Priority: 2] {TCP} 10.10.1.254:34053 -> 69.164.26.77:80 
1 --> ids-01p --> 36:50 IDS01 SFIMS: [FLIDS][Enterprise][138:4:1] sensitive_data: sensitive data - U.S. social security numbers without dashes [Classification: Sensitive Data] [Priority: 2] {TCP} 10.1.65.51:57977 -> 216.137.41.5:80 
2 --> ids-01p --> 36:53 IDS01 SFIMS: [FLIDS][Enterprise][128:4:1] ssh: Protocol mismatch [Classification: Detection of a Non-Standard Protocol or Event] [Priority: 2] {TCP} 10.10.241.46:11120 -> 10.10.125.227:22 
3 --> ids-01p --> 36:54 IDS01 SFIMS: [FLIDS][Enterprise][128:4:1] ssh: Protocol mismatch [Classification: Detection of a Non-Standard Protocol or Event] [Priority: 2] {TCP} 10.10.241.46:11122 -> 10.1.125.225:22 
4 --> ids-01p --> 36:54 IDS01 SFIMS: [FLIDS][Enterprise][138:4:1] sensitive_data: sensitive data - U.S. social security numbers without dashes [Classification: Sensitive Data] [Priority: 2] {TCP} 10.1.118.96:61686 -> 50.19.254.195:80 
5 --> ids-01p --> 36:54 IDS01 SFIMS: [FLIDS][Enterprise][138:4:1] sensitive_data: sensitive data - U.S. social security numbers without dashes [Classification: Sensitive Data] [Priority: 2] {TCP} 10.1.1.254:29437 -> 184.73.178.248:80 

답변

2

한 가지를 들어, 당신이 (..., @set, $hypertable) 인수를 사용하여 스레드 생성자를 호출하지만 스레드에서 shift을 사용하여 @set을 할당하기 전에 $hypertable을 입력하십시오.

my $hypertable = pop; # same as pop(@_) 
: 당신은 @_ 대신 (처음부터 그것을 제거하는) shift의 끝에서 인수를 제거하려면

threads->create('logsys',$hypertable,@set); 

로, 인수의 순서를 변경하거나 pop을 사용하기를 원할 것 중 하나

두 번째로 @set = shift과 같은 할당은 거의 항상 잘못된 것입니다. 하나의 스칼라 값인 shift의 반환 값을 목록에 할당하는 것은 드문 경우입니다. 당신이 스레드에서 $hypertable을 할당하고, @_에서 값을 제거하면 @_에 남아있는 모든 사용자가 제공 한 @set, 그래서 당신은

my @set = @_; 

@set->[...]는 펄에서 의미가 없습니다 말할 수 있습니다. 스레드에서 2 차원 배열 @set의 요소에 액세스하려면, 당신은 배열을 만드는 데 사용 된 동일한 표기법을 사용할 수 있습니다

print $count." --> ".$set[$count][0]." --> ".$set[$count][1]."\n"; 
+0

나는 이것을 시도했지만 지금은 다른 이슈로 실행 중이다. 스레드가 일관성이 없다. 테스트를 위해서만 배열을 전달했지만 스레드는 배열의 모든 값을받지 못합니다. –

+0

서브 루틴에서 서브를 실행하지 않으면 배열의 모든 요소를 ​​받겠지만 스레드로 실행하면 모든 요소가 수신되지 않습니다. –

+0

새 질문이 편집 됨. –

0

사람들은 스레드가 느리다 불평을하지만, 부적절하게 사용 할 때 그 단지의 예를 들어, 작업 스레드를 사용하는 대신 많은 스레드를 생성하는 경우. 여기

당신이 당신의 코드에서이 문제를 해결할 수있는 방법은 다음과 같습니다 하나의 DB 스레드를 가짐으로써

use threads; 
use Thread::Queue::Any 1.03 qw(); 

sub logsys {      # Gets a reference, so uses 
    my ($hypertable, $set) = @_; # @$set and $set->[...] 
    ... $set->[...][...] ...  # instead of 
}         # @set and $set[...] 

my $db_queue = Thread::Queue::Any->new(); 

my $db_thread = async { 
    my $hypertable = ...; # Only executed once. 
    while (my $set = $db_queue->dequeue()) { 
     logsys($hypertable, $set); 
    } 
}; 

... $db_queue->enqueue(\@set); ... 

$db_queue->enqueue(undef); # Signal that we're done. 
$db_thread->join();   # Wait for db to be done. 

, 그것은 또한 모든 스레드에 대해 하나의 DB 연결이 당신의 불가능 욕망을 해결합니다.

+0

위의 내 코멘트를 참조하십시오. –

+0

새 질문이 편집되었습니다. –

+0

나는 이미 너에게 내 조언을 주었다. 그걸 가져 가고 싶지 않다면, 괜찮습니다. 그러나 원래 일을하는 방식에 여전히 문제가 있다는 말을하지 마십시오. – ikegami

관련 문제