Flock não parece estar funcionando

6

Recentemente, tentei criar um script de shell para um projeto secundário e, por algum motivo, o comando flock não está funcionando corretamente para mim. Sempre que eu invoco em um subshell o caminho atômico e o coloco em segundo plano, outros programas parecem ser capazes de ler / escrever no arquivo bloqueado.

Sessão de bash:

guest@guest ~ $ touch ./temp
guest@guest ~ $ ( flock -x 3 && sleep 99999999999; ) 3>./temp &
[1] 22874
guest@guest ~ $ cat ./temp 
guest@guest ~ $ echo this is a test >./temp 
guest@guest ~ $ cat ./temp 
this is a test
guest@guest ~ $ jobs
[1]+  Running                 ( flock -x 3 && sleep 99999999999 ) 3>./temp &
guest@guest ~ $ bash --version
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Eu sinto que posso estar perdendo algo muito simples em relação aos internos do programa 'bando', mas não sei o que poderia ser.

    
por Mr. Minty Fresh 24.08.2017 / 04:24

1 resposta

7

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

    
por 24.08.2017 / 09:26