使用Fcntl flock()对于处理互斥量是否可靠? [PERL]

时间:2015-04-28 04:56:30

标签: perl mutex flock

我创建了一个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

0 个答案:

没有答案