В Perl, как я могу проверить, заблокирован ли файл? - PullRequest
6 голосов
/ 21 декабря 2010

Как именно я проверю, чтобы убедиться, что файл заблокирован исключительно?У меня есть эта функция, но она возвращает 1 независимо от того, что я делаю:

sub is_file_locked
{
  my $theFile;
  my $theRC;

  ($theFile) = @_;
  $theRC = open(HANDLE, $theFile);
  $theRC = flock(HANDLE, LOCK_EX|LOCK_NB);
  close(HANDLE);
  return !$theRC;
}

Ответы [ 3 ]

9 голосов
/ 21 декабря 2010

Вы открыли $theFile в режиме чтения, и LOCK_EX не предназначен для использования таким образом .

Обратите внимание, что эмуляция fcntl (2) в flock (3) требует FILEHANDLE должен быть открыт для чтения с намерением использовать LOCK_SH и требует чтобы он был открыт с намерением записи использовать LOCK_EX.

6 голосов
/ 21 декабря 2010

Прежде всего, вы должны проверить, успешно ли open.

Кроме того, вы должны проверить, можете ли вы получить общую блокировку.flock с LOCK_EX (я думаю) потерпит неудачу, если существует общая блокировка для файла.

Однако файл может заблокироваться между проверкой и возвратом, создавая состояние гонки, поэтомутакая функция имеет сомнительное значение.

#!/usr/bin/perl

use strict; use warnings;
use Fcntl qw( :flock );

print is_locked_ex($0)
      ? "$0 : locked exclusively\n"
      : "$0 : not locked exclusively\n";

my $test_file = 'test.txt';
open my $fh, '>', $test_file
    or die "Cannot open '$test_file' for writing: $!";

if ( flock $fh, LOCK_EX|LOCK_NB ) {
    print is_locked_ex($test_file)
          ? "$test_file : locked exclusively\n"
          : "$test_file : not locked exclusively\n";
}

close $fh or die "Cannot close '$test_file': $!";

sub is_locked_ex {
    my ($path) = @_;

    die "Not a plain file: '$path'" unless -f $path;
    return 1 unless open my $fh, '<', $path;

    my $ret = not flock $fh, LOCK_SH | LOCK_NB;
    close $fh
        or die "Cannot close '$path': $!";

    return $ret;
}
0 голосов
/ 22 декабря 2010

Окончательное решение:

flock($fh, LOCK_EX) or die "Cannot lock file - $!\n";

if ( is_file_locked($gTestQueuePath) ){ print "locked";} else { print "not locked";}

#1 = locked 0 = not locked
sub is_file_locked
{
  my $theFile;
  my $theRC;

  ($theFile) = @_;
  $theRC = open(my $HANDLE, ">>", $theFile);
  $theRC = flock($HANDLE, LOCK_EX|LOCK_NB);
  close($HANDLE);
  return !$theRC;
}

close $fh or die "Cannot close";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...