flock
bloqueia o aviso, que é um esquema de bloqueio cooperativo. Isso significa que você será capaz de substituir o bloqueio se não cooperar.
Você coopera solicitando a trava antes de fazer a operação e liberando a trava depois de terminar. É a operação que é protegida pelo bloqueio, não (necessariamente) o próprio arquivo de bloqueio.
De o manual flock(2)
no meu sistema:
Advisory locks allow cooperating processes to perform consistent operations on files, but do not guarantee consistency (i.e., processes may still access files without using advisory locks possibly resulting in inconsistencies).
Considere este script:
#!/bin/sh
( flock -x 9 || exit 1
echo '1: Locking for 5 secs'; sleep 5; echo '1: Done' ) 9>/tmp/lock &
sleep 1
echo '2: Will now attempt to get lock'
( flock -x 9 || exit 1
echo '2: Got lock' ) 9>/tmp/lock
# Since the second flock call only performs one operation, the whole last
# subshell may be replaced by just
# flock -x /tmp/lock -c echo '2: Got lock'
#
# (-x and -c are not needed, a lock is exclusive ("write lock")
# unless -s is used to create a shared lock ("read lock"),
# and the -c is optional)
Saída:
1: Locking for 5 secs
2: Will now attempt to get lock
1: Done
2: Got lock
Você pode ver que o bloqueio foi adquirido pelo processo em segundo plano e que a outra chamada flock
precisou aguardar que ele fosse liberado antes de poder bloqueá-lo.
Observe também que o arquivo de bloqueio não é o que está protegido aqui, são as operações echo
nas subshells que são garantidas como exclusivas. Em particular, o arquivo de bloqueio não é protegido contra processos não cooperativos que escrevem ou lêem a partir dele.
Isso significa que cada subcamada flock
, bloqueando /tmp/lock
neste exemplo, garante que as operações (em arquivos ou outros recursos de dados compartilhados) não serão misturadas com operações conflitantes de qualquer outro programa que usa flock
com /tmp/lock
como o arquivo de bloqueio.
Para ilustrar o último parágrafo acima, execute meu script acima em dois terminais diferentes (possivelmente com um pouco mais de tempo de suspensão), o mais simultaneamente possível, e verifique se os dois scripts concorrentes adquirem os bloqueios adequadamente (aguardando um ao outro). Como um bloqueio é solicitado em um processo de segundo plano, isso significa que os bloqueios podem ser adquiridos fora de ordem do especificado no script ao executar duas instâncias do script simultaneamente.
No seu exemplo, o shell interativo está não cooperando com o mecanismo de bloqueio . É por isso que você é capaz de ler e gravar no arquivo, mesmo que o bloqueio seja mantido pela subcamada em segundo plano.
Note também que nem todos os sistemas de arquivos podem suportar o bloqueio de arquivos com flock
(ou seu equivalente na biblioteca C, flock()
). Por exemplo, os sistemas de arquivos de rede AFS e NFS podem ser problemáticos a esse respeito. Consulte o link