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 ホストごとに 1 つのスレッドを使用してコードを改善することを考えていました。このために、いくつかのコードを試しましたが、以下のコードでいくつかの成功を収めました。

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 乾杯!!

-アヴィ・メヘンワル

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 に答える