Perl - 线程连接和系统内存不足

时间:2013-05-03 16:45:32

标签: arrays multithreading perl

我在我的Perl代码中为数组和线程发布了couple of question。这是代码。 基于这些建议,我做了改动,似乎工作正常。代码仍然遇到了一个新问题。机器内存不足。许多线程已完成且未连接。

代码 -

#!/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;
my $thr;
# Start Listening on UDP port 514
$sock = IO::Socket::INET->new(LocalPort => '514', Proto => 'udp') || die("Socket: $@");

my $buf = '';
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][3] = $msg;
  print $count." --> ".$set[$count][0]." --> ".$set[$count][4]."\n";#Print original array, should print 5 elements 

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

  #&logsys(@set);
}
}while(1);

$thr->join();

sub logsys {
  my $count = 0;
  my @set = @_;
  my $geoip = Geo::IP->new(GEOIP_CHECK_CACHE);
  my $nb = Net::NBName->new;

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

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

错误 -

Out of memory!
Callback called exit at /usr/lib/perl/5.10/IO/Socket.pm line 287.
Thread 646 terminated abnormally: main=HASH(0xee3b3068) at ./syslogd.pl line 50.
Perl exited with active threads:
        9 running and unjoined
        644 finished and unjoined
        0 running and detached

这是什么意思?即使很多线程完成,为什么机器内存不足?我该如何解决?如果需要,我可以提供更多信息。

1 个答案:

答案 0 :(得分:1)

您需要joindetach线程来释放他们保留的内存。

只需添加:

$thr->detach();
创建线程后的

,或者在完成后创建一个专用线程来加入其他线程,如果你需要以某种方式检索它们的结果。

看到你的代码更新,你似乎想加入创建的线程,但是你试图在do循环之外这样做,这似乎并没有结束。因此,join电话显然从未达成过。即使它确实如此,$thr变量也只包含对最新创建的线程的引用,因此只允许加入该实例。

鉴于我对您的代码的看法,我认为最好的做法是让您的线程以分离状态运行,并让它们按需要返回的方式推送到队列。