Я хотел бы определить, какой процесс имеет владение файла блокировки. Файлы блокировки являются просто файлом с собственным именем, которое было создано.
Так, как я могу определить, какой процесс имеет конкретный файл, открытый в Linux? Предпочтительно тип остроты или конкретное решение для инструмента Linux были бы оптимальны.
Можно также использовать fuser
для этого:
~> less .vimrc
# put in background
~> fuser .vimrc
.vimrc: 28135
~> ps 28135
PID TTY STAT TIME COMMAND
28135 pts/36 T 0:00 less .vimrc
В большинстве систем Linux lsof NAME
делает задание:
fin@r2d2:~$ lsof /home/fin
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
bash 21310 fin cwd DIR 8,1 4096 5054467 /home/fin
lsof 21320 fin cwd DIR 8,1 4096 5054467 /home/fin
lsof 21321 fin cwd DIR 8,1 4096 5054467 /home/fin
fin@r2d2:~$
Наличие открытого файла не является блокировкой, потому что, если каждый процесс должен проверить, является ли файл открытым первый и не продолжается, если это - или создает/открывает его, если это не, затем два процесса могли бы вполне хорошо проверить одновременно, оба находят, что это не открыто, затем оба создают или открывают его.
Для использования файла в качестве блокировки операция проверки-и-блокировки должна быть единственной непрерываемой операцией. Можно достигнуть этого в файловой системе Unix путем создания файла с режимом только для чтения и удаления его для разблокирования. Если файл будет существовать (и только для чтения), то создание файла перестанет работать, таким образом, Вы получите проверку-и-блокировку в единственной атомарной операции.
Если Ваш процесс блокировки является сценарием оболочки, который будет работать как демон, можно получить этот эффект при помощи umask
, установка для каждого процесса, которая устанавливает полномочия, с которыми создаются новые файлы:
oldumask=$(umask) umask 222 # create files unwritable to owner too if echo $$ > /var/lock/foo then : locking succeeded else : locking failed fi umask $oldumaskЭто также пишет процессу владения PID в файл, который решает Вашу другую проблему:
cat /var/lock/foo
/proc
как корень: ls -l /proc/*/cwd | grep '/var/lock/foo$'
или, как смертный пользователь:
ls -l /proc/*/cwd 2>/dev/null | grep '/var/lock/foo$'