무리가 작동하지 않는 것 같습니다

무리가 작동하지 않는 것 같습니다

최근에 소규모 프로젝트를 위한 셸 스크립트를 만들려고 했는데 어떤 이유로 명령 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파일 잠금을 위한 다른 프로그램으로 함께 사용하세요 .

위의 마지막 단락을 설명하기 위해 가능하면 위의 스크립트를 두 개의 서로 다른 터미널에서 동시에 실행하고(휴면 시간을 약간 늘릴 수도 있음) 두 경쟁 스크립트가 적절하게 잠금을 획득하는지 확인합니다(서로를 기다림). 백그라운드 프로세스에서 잠금이 요청되므로 이는 잠금이가능한두 개의 스크립트 인스턴스를 동시에 실행할 때 스크립트에 지정된 순서대로 얻을 수 없습니다.

귀하의 예에서 대화식 쉘은 다음과 같습니다.잠금 메커니즘에 협조하지 않음. 이것이 백그라운드 서브셸이 잠금을 보유하더라도 파일을 읽고 쓸 수 있는 이유입니다.

또한 모든 파일 시스템이 flockC++(또는 이에 상응하는 C 라이브러리 flock())를 사용한 파일 잠금을 지원하는 것은 아닙니다. 예를 들어, 네트워크 파일 시스템 AFS 및 NFS에는 이와 관련하여 문제가 있을 수 있습니다. 바라보다https://en.wikipedia.org/wiki/File_locking#Problems

관련 정보