背景:
私の perl スクリプトをマルチスレッド化する方法を読む際に、( http://perldoc.perl.org/threads.html#BUGS-AND-LIMITATIONSから)を読みました
ほとんどのシステムでは、スレッドの頻繁かつ継続的な作成と破棄により、Perl インタープリターのメモリ フットプリントがますます増大する可能性があります。スレッドを起動してから ->join() または ->detach() するのは簡単ですが、寿命の長いアプリケーションの場合は、スレッドのプールを維持し、キューを使用して必要な作業にそれらを再利用することをお勧めします。スレッドに保留中の作業を通知します。
私のスクリプトは長持ちします。これは、常に実行されている PKI LDAP ディレクトリ監視デーモンです。エンタープライズ監視ソリューションは、何らかの理由で実行を停止するとアラームを生成します。私のスクリプトは、別の PKI LDAP ディレクトリにアクセスできることを確認し、両方の失効リストを検証します。
問題: Google で見つけることができるすべてのものは、サブルーチン自体ではなく、変数 (スカラーなど) をスレッド キューに渡すことを示しています...スレッドの実装方法と比較して、スレッド キューを適切に実装する方法を理解していないと思います (キューなし)。
質問 1 : perl インタープリターがメモリを徐々に消費するのを避けるために、「スレッドのプールを維持する」にはどうすればよいですか?
質問2: (関係ありませんが、このコードを投稿している間) スレッドを 1 分間に 2 回以上開始しないように、メイン プログラムの最後に安全な量のスリープがありますか? 60 は当たり前のように思えますが、ループが高速な場合、または処理時間などのために 1 分も逃した場合に、ループが複数回実行される可能性はありますか?
前もって感謝します!
#!/usr/bin/perl
use feature ":5.10";
use warnings;
use strict;
use threads;
use Proc::Daemon;
#
### Global Variables
use constant false => 0;
use constant true => 1;
my $app = $0;
my $continue = true;
$SIG{TERM} = sub { $continue = false };
# Directory Server Agent (DSA) info
my @ListOfDSAs = (
{ name => "Myself (inbound)",
host => "ldap.myco.ca",
base => "ou=mydir,o=myco,c=ca",
},
{ name => "Company 2",
host => "ldap.comp2.ca",
base => "ou=their-dir,o=comp2,c=ca",
}
);
#
### Subroutines
sub checkConnections
{ # runs every 5 minutes
my (@DSAs, $logfile) = @_;
# Code to ldapsearch
threads->detach();
}
sub validateRevocationLists
{ # runs every hour on minute xx:55
my (@DSAs, $logfile) = @_;
# Code to validate CRLs haven't expired, etc
threads->detach();
}
#
### Main program
Proc::Daemon::Init;
while ($continue)
{
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
# Question 1: Queues??
if ($min % 5 == 0 || $min == 0)
{ threads->create(&checkConnections, @ListOfDSAs, "/var/connect.log"); }
if ($min % 55 == 0)
{ threads->create(&validateRevocationLists, @ListOfDSAs, "/var/RLs.log"); }
sleep 60; # Question 2: Safer/better way to prevent multiple threads being started for same check in one matching minute?
}
# TERM RECEIVED
exit 0;
__END__