Приведенная ниже подпрограмма Perl использует File::FcntlLock
для проверки того, заблокирован ли файл.
Почему он возвращает 0
и печатает /tmp/test.pid is unlocked.
, даже если файл заблокирован?
sub getPidOwningLock {
my $filename = shift;
my $fs = new File::FcntlLock;
$fs->l_type( F_WRLCK );
$fs->l_whence( SEEK_SET );
$fs->l_start( 0 );
$fs->l_len( 0 );
my $fd;
if (!open($fd, '+<', $filename)) {
print "Could not open $filename\n";
return -1;
}
if (!$fs->lock($fd, F_GETLK)) {
print "Could not get lock information on $filename, error: $fs->error\n";
close($fd);
return -1;
}
close($fd);
if ($fs->l_type() == F_UNLCK) {
print "$filename is unlocked.\n";
return 0;
}
return $fs->l_pid();
}
Файл заблокирован следующим образом (lock.sh):
#!/bin/sh
(
flock -n 200
while true; do sleep 1; done
) 200>/tmp/test.pid
Файл действительно заблокирован:
~$ ./lock.sh &
[2] 16803
~$ lsof /tmp/test.pid
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 26002 admin 200w REG 8,5 0 584649 test.pid
sleep 26432 admin 200w REG 8,5 0 584649 test.pid
flock($fd,6)
показывает, что файл заблокирован. - person mob   schedule 15.02.2017F_GETLK
? СF_GETLK
методlock()
определяет, удерживает ли процесс блокировку в данный момент и какой именно. Если другой блокировки нет, для свойстваl_type
будет установлено значениеF_UNLCK
. - person ThisSuitIsBlackNot   schedule 15.02.2017flock
не то же самое, чтоfcntl
. См. man(2) flock: Начиная с ядра 2.0, flock() реализован как системный вызов. сам по себе, а не эмулируется в библиотеке GNU C как вызов fcntl(2). Это дает истинную семантику BSD: нет никакого взаимодействия между типами блокировок, устанавливаемых flock() и fcntl(2)... - person ThisSuitIsBlackNot   schedule 15.02.2017fcntl
иflock
. - person   schedule 15.02.2017