【问题标题】:Perl - threads join and system running out of memoryPerl - 线程加入和系统内存不足
【发布时间】:2013-05-04 02:33:24
【问题描述】:

我在我的 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

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

【问题讨论】:

  • 你为什么不关闭文件句柄?另外,使用词法文件句柄。分离或加入您的线程,具体取决于您要实现的目标。

标签: arrays multithreading perl


【解决方案1】:

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

只需添加:

$thr->detach();

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

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

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

【讨论】:

  • 请再看一遍代码,我错过了一部分,编辑了我的问题以添加正确的代码。我无休止地运行一个 do while 循环并执行 thr->join();依然报出内存不足的错误。
  • 所以我应该在 do-while 循环中执行$thr = threads-&gt;create('logsys',@set,$hypertable); $thr-&gt;detach();。这将创建一个线程并将其分离,一旦线程结束,内存将自动释放。
  • 这就是线程 doxumentation 所说的。但是,您应该尽快正确关闭所有文件句柄并释放线程使用的已分配资源,以便在线程执行期间的任何时候拥有尽可能多的空闲内存。
  • 谢谢,我做出了改变,现在看起来好多了。有没有办法显示所有创建的线程的状态?
  • 使用threads-&gt;list() 获取现有线程的列表,并使用is_runningis_joinableis_detached 方法了解每个线程的状态。
猜你喜欢
  • 2018-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多