0

我在我的 Perl 代码中发布了几个 关于数组和线程的问题。这里又是代码。根据建议,我进行了更改,它似乎正在工作。代码仍然遇到了新问题。机器内存不足。许多线程已完成且未连接。

代码-

#!/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

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

4

1 回答 1

1

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

只需添加:

$thr->detach();

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

看到你对代码的更新,你似乎想加入创建的线程,但是你尝试在do循环之外这样做,这似乎并没有结束。因此,join显然永远无法接通电话。即使是这样,该$thr变量也只会包含对最新创建的线程的引用,因此只允许加入该实例。

鉴于我对您的代码的看法,我认为最好的做法是让您的线程在分离状态下运行,并让它们推送到队列中,无论它们需要返回什么结果。

于 2013-05-03T17:42:21.580 回答