0

祝大家新年快乐 :D

我已经用 perl 编写了一段代码,它运行良好,但我期待利用多线程和进程分叉等特性来增强该代码。代码旨在用于以下任务:

  1. 持续记录列表中提供的多个服务器的 ping。
  2. 分别为每个被 ping 的主机维护和写入日志。
  3. 在实时命令窗口中显示实时统计信息。

完整代码为:

#!/user/perl/bin 
use strict;
use Net::Ping;
use Time::HiRes;
use IO::Handle;
use threads;
use threads::shared;

#       AUTHOR  :       Avi Mehenwal
#       PURPOSE :       Continuous ping check with PERL iThreads (interpreted threads)
#       DATE    :       10th-Jan-2013

sub Ping {

#Filer handle generation and open log file for writing in append mode.
#creating ping object to check ping response
#Writing Ping results in logs and command window for Real time analysis
#Close file after logs are witten

    my ($host , $protocol) = @_;
    chop $host;
    open my $log, '>>', "Ping_$host.txt" or die "Cannot create log file: $!";
    $log->autoflush;                                                          #autoflusing to stop output stream buffering.      
    my $p = Net::Ping->new($protocol) or die "Cannot create new Net::Ping object : $!";
    $p->hires;
    my ($ret, $duration, $ip) = $p->ping($host);
    if ($ret=='1')
     {    my $event = sprintf "%s\t%s is alive $protocol (packet RTT: %.3fms)\n",
                             scalar localtime, $host, $duration;
          print STDOUT $event;
          print $log $event;
          sleep(1);  #sleep only when ping is continuous    
      }
    else
     {    my $event = sprintf "%s\t%s is UNAVAILABLE (Timedout/lost $protocol request)\n",
                                            scalar localtime, $host;
          print STDOUT $event;
          print $log $event;               
     }
    close $log; 
}

my @hostip = qw(10.98.10.253, 10.112.114.10, 10.112.114.11);
STDOUT->autoflush;
print "****************************************************************************\n\ncPING-CHECK -v2.0 By-Avi Mehenwal\n\n";
print "Kindly enter the protocol to be used by cPing-Probe : tcp / udp / icmp ...\n";
my $protocol = <STDIN>;
chomp $protocol;
if($protocol eq "icmp") {
 print "\nWARNING:For cPing-Probe to use icmp protocol kindly run the program in administrative command prompt\ncPing-Probe v2.0will now exit ...";
 sleep(10);
 exit;
}      

while(1)      {
 foreach my $thost (@hostip) {
   Ping($thost,$protocol);
 }     
}     

#END 

现在我正在考虑使用每个 ip 主机一个线程来改进我的代码,这将检查 ping 和写入日志而不影响其他主机 ip 线程。为此,我尝试了几个代码,但我发现以下代码取得了一些成功:

my @hostip = qw(10.98.10.253, 10.112.114.10, 10.112.114.11);
STDOUT->autoflush;
print "****************************************************************************\n\ncPING-CHECK -v2.0 By-Avi Mehenwal\n\n";
print "Kindly enter the protocol to be used by cPing-Probe : tcp / udp / icmp ...\n";
my $protocol = <STDIN>;
chomp $protocol;
if($protocol eq "icmp") {
 print "\nWARNING:For cPing-Probe to use icmp protocol kindly run the program in administrative command prompt\ncPing-Probe v2.0will now exit ...";
 sleep(10);
 exit;
}      

while(1)
{   my $thr;
foreach my $thost (@hostip) 
{       $thr = threads->new(Ping,$thost,$protocol) or die "Cannot Create thread : $!";  #seperate thread for each IP
    Ping($thost,$protocol);
    }
    if($thr->is_joinable())
     {       $thr->join(); 
             print STDOUT "Thread joined\n";   }
    else
      {      $thr->detach();
             print STDOUT "Thread detached\n"; }     
}     

#END

但是这段代码有一些不需要的症状,我需要专家的帮助。

  • 为什么我会生成一个名为 Ping_ 的日志文件并将日志写入其中!理想情况下,每个主机都需要日志文件。我无法理解这里的诀窍。
  • 我的代码是否真的在为每个主机并行运行线程进行多任务处理?我怎样才能检查或确定这一点?
  • 有没有更好的方法来完成我的工作?
  • 您认为我可以将任何其他功能添加到我的代码中吗?

提前感谢大家:D干杯!

-Avi Mehenwal

4

1 回答 1

0
  1. 根本不要使用线程;在 Perl 中,它们是邪恶的。
  2. 不要用于forkI/O 密集型任务。

AnyEvent::Ping似乎完全符合您的要求:

#!/usr/bin/env perl
use common::sense
use AnyEvent;
use AnyEvent::Ping;
 
my $c = AnyEvent->condvar;
 
my $ping = AnyEvent::Ping->new;
 
$ping->ping('google.com', 1, sub {
    my $result = shift;
    print "Result: ", $result->[0][0],
      " in ", $result->[0][1], " seconds\n";
    $c->send;
});
 
$c->recv;
于 2013-01-14T14:20:41.993 回答