我创建了一个perl脚本,如下所示 - (仅显示相关的代码片段)
#!/appl/pm/vendor/perl/lx-x86/5.14.2/bin/perl -w
my $no_of_retries = 60;
my $sleep_time = 60;
use Fcntl qw(:flock SEEK_END);
#-------------------------------------------------------------------------------
# To allow only one instance loader program to run
#-------------------------------------------------------------------------------
sub SyncWaitForFile($$$) {
my ($delay_file, $no_of_retries, $sleep_time) = @_;
#check for delay file
my $minutes_passed = 0;
while ( (-e $delay_file) && (--$no_of_retries) && ($no_of_retries > 0) )
{
if ( (($minutes_passed / 10) == 0) && ($minutes_passed != 0)) # Check Every 10 minutes and send mail
{
MailNotify ("Loader with [PID=$$;hostname=$host;user=$ENV{'LOGNAME'}] is waiting for $minutes_passed minutes for delay file to be removed", "Delay File => $delay_file", $maillist);
}
Logger::info ("Waiting for removal of delay_file $delay_file for $sleep_time seconds. Time passed waiting => $minutes_passed minutes. Number of retries remaining : $no_of_retries");
sleep($sleep_time);
++$minutes_passed;
}
if ($no_of_retries <= 0)
{
MailNotify ("Loader with [PID=$$;hostname=$host;user=$ENV{'LOGNAME'}] has exited due to non-removal of delay file", "Delay File => $delay_file", $maillist);
ErrorExit("Couldn't Acquire Exclusive Lock. loader.pl cannot run in parallel. So Exiting", 1, 0);
}
while(1)
{
my $flockfile = "${delay_file}.flockFile";
open (my $handle, ">" , $flockfile) or ErrorExit("Not able to open file $flockfile", -1, 0);
Logger::info "Acquiring lock on $flockfile";
flock($handle, LOCK_EX) or ErrorExit("Failed during lock", -1, 0); #Take the lock
#Check again for delay file as while the time this process took the lock,
#by that time some other process may took lock created the delay file and release the lock
if (-e $delay_file)
{
Logger::info "Releasing lock on $flockfile";
flock($handle, LOCK_UN); # Unlocks the delay file
# Wait till this delay_file is removed
Logger::info "Waiting for removal of delay_file $delay_file";
while ( (-e $delay_file) && (--$no_of_retries) && ($no_of_retries > 0) )
{
if ( (($minutes_passed / 10) == 0) && ($minutes_passed != 0) )
{
MailNotify ("Loader with [PID=$$;hostname=$host;user=$ENV{'LOGNAME'}] is waiting for $minutes_passed minutes for delay file to be removed", "Delay File => $delay_file", $maillist);
}
Logger::info ("Waiting for removal of delay_file $delay_file for $sleep_time seconds. Time passed waiting => $minutes_passed. Number of retries remaining : $no_of_retries");
sleep($sleep_time);
++$minutes_passed;
}
if ($no_of_retries <= 0)
{
MailNotify ("Loader with [PID=$$;hostname=$host;user=$ENV{'LOGNAME'}] has exited due to non-removal of delay file", "Delay File => $delay_file", $maillist);
ErrorExit("Couldn't Acquire Exclusive Lock. loader.pl cannot run in parallel. So Exiting", -1, 0);
}
else
{
next;
}
}
Logger::info "Creating delay file $delay_file";
open (DELAY_FILE, "> $delay_file") or ErrorExit("ERROR: Unable to open file:$delay_file $!", -1, 0);
print DELAY_FILE "Locked by Loader with [PID=$$;hostname=$host;user=$ENV{'LOGNAME'}]\n";
close(DELAY_FILE);
Logger::info "Releasing lock on $flockfile";
flock($handle, LOCK_UN); # Unlocks the flock file
last;
}}
上述代码在压力测试下失败。 我运行了25个并行实例,它运行正常。
但是当系统达到50多个并行实例时,等待delay_file获得释放,它就被阻止了。 大多数装载机在下一行失败了 -
flock($handle, LOCK_EX) or ErrorExit("Failed during lock", -1, 0);
我只有两个问题 -
[1] 负载增加时可能出现故障的原因是什么?(当负载较小时,它没有失败)
[2] 在PERL中处理互斥锁的最佳方法是什么,即使在负载过大的情况下也能正常工作?
我在Linux上使用PERL -
PERL - 5.14.2
Linux - RHEL Server 5.11