최근에 소규모 프로젝트를 위한 셸 스크립트를 만들려고 했는데 어떤 이유로 명령 flock
이 작동하지 않습니다. 서브셸에서 원자적으로 호출하여 백그라운드에 넣을 때마다 다른 프로그램이 잠긴 파일을 읽고 쓸 수 있는 것 같습니다.
쿵쿵 세션:
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.
나는 "군집" 프로그램의 내부와 관련된 매우 간단한 것을 놓친 것 같지만 그것이 무엇인지 전혀 모릅니다.
답변1
flock
협업 잠금 방식인 권고 잠금을 수행합니다. 이는 협조하지 않으면 잠금을 무시할 수 있음을 의미합니다. 작업을 수행하기 전에 잠금을 요청하고 작업이 완료된 후 잠금을 해제하는 방식으로 협조할 수 있습니다. 이는 (반드시) 잠금 파일 자체가 아닌 잠금으로 보호되는 작업입니다.
~에서flock(2)
수동내 시스템에서:
권고 잠금을 사용하면 협력 프로세스가 파일에 대해 일관된 작업을 수행할 수 있지만 일관성은 보장되지 않습니다(즉, 프로세스는 권고 잠금을 사용하지 않고도 파일에 계속 액세스할 수 있으므로 불일치가 발생할 수 있음).
다음 스크립트를 고려해보세요.
#!/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)
산출:
1: Locking for 5 secs
2: Will now attempt to get lock
1: Done
2: Got lock
백그라운드 프로세스가 잠금을 획득하고 다른 flock
호출이 잠금을 해제하려면 잠금이 해제될 때까지 기다려야 함을 알 수 있습니다.
또한 여기서 보호되는 것은 잠긴 파일이 아니라 echo
배타성이 보장되는 서브셸의 작업이라는 점에 유의하세요. 특히 잠금 파일은 비협조적인 프로세스 쓰기 또는 읽기로부터 보호되지 않습니다.
이는 flock
이 예에서 잠금을 통해 /tmp/lock
각 하위 쉘의 작업(파일 또는 기타 공유 데이터 리소스에 대한 작업)이 다른 하위 쉘의 충돌하는 작업과 혼합되지 않도록 보장한다는 의미입니다.어느flock
/tmp/lock
파일 잠금을 위한 다른 프로그램으로 함께 사용하세요 .
위의 마지막 단락을 설명하기 위해 가능하면 위의 스크립트를 두 개의 서로 다른 터미널에서 동시에 실행하고(휴면 시간을 약간 늘릴 수도 있음) 두 경쟁 스크립트가 적절하게 잠금을 획득하는지 확인합니다(서로를 기다림). 백그라운드 프로세스에서 잠금이 요청되므로 이는 잠금이가능한두 개의 스크립트 인스턴스를 동시에 실행할 때 스크립트에 지정된 순서대로 얻을 수 없습니다.
귀하의 예에서 대화식 쉘은 다음과 같습니다.잠금 메커니즘에 협조하지 않음. 이것이 백그라운드 서브셸이 잠금을 보유하더라도 파일을 읽고 쓸 수 있는 이유입니다.
또한 모든 파일 시스템이 flock
C++(또는 이에 상응하는 C 라이브러리 flock()
)를 사용한 파일 잠금을 지원하는 것은 아닙니다. 예를 들어, 네트워크 파일 시스템 AFS 및 NFS에는 이와 관련하여 문제가 있을 수 있습니다. 바라보다https://en.wikipedia.org/wiki/File_locking#Problems