Ter um ficheiro aberto não é um bloqueio porque, se cada processo tem de verificar se o ficheiro está aberto primeiro e não proceder se está ou criar/abrir se não está, então dois processos podem muito bem verificar simultaneamente, ambos descobrem que não está aberto, depois ambos criam ou abrem.
Para utilizar um ficheiro como bloqueio, a operação de verificação e bloqueio tem de ser uma única operação ininterrupta. Pode conseguir isto num sistema de ficheiros Unix, criando um ficheiro com modo só de leitura e removendo-o para o desbloquear. Se o ficheiro existir (e for apenas de leitura), a criação do ficheiro falhará, pelo que obtém o check-and-lock numa única operação atómica.
Se o seu processo de bloqueio é um script shell que estará a correr como um daemon, pode obter este efeito usando umask
, uma configuração por processo que define as permissões com que os novos ficheiros são criados:
oldumask=$(umask) umask 222 # create files unwritable to owner too if echo $$ \> /var/lock/foo then : locking succeeded else : locking failed fi umask $oldumask
Isto também escreve o PID do próprio processo no ficheiro, o que resolve o seu outro problema: cat /var/lock/foo
No que diz respeito à questão específica “Que processos têm este ficheiro aberto? ”, isto pode ser útil quando pretende desmontar um sistema de ficheiros mas não pode porque algum processo tem um ficheiro aberto nele. Se não tem esses comandos disponíveis, pode perguntar ao /proc
como raiz:
ls -l /proc/*/cwd | grep '/var/lock/foo$'
ou, como utilizador mortal:
ls -l /proc/*/cwd 2>/dev/null | grep '/var/lock/foo$'