[python] 파이썬에서 파일 잠금

파이썬으로 작성하려면 파일을 잠 가야합니다. 여러 Python 프로세스에서 한 번에 액세스합니다. 온라인에서 일부 솔루션을 찾았지만 대부분 유닉스 기반 또는 Windows 기반이기 때문에 대부분 내 목적에 실패합니다.



답변

좋아, 그래서 나는 여기에 쓴 코드로 끝났고 , 내 웹 사이트 링크가 죽었습니다. archive.org ( GitHub에서도 가능)에서 볼 수 있습니다 . 다음과 같은 방식으로 사용할 수 있습니다.

from filelock import FileLock

with FileLock("myfile.txt.lock"):
    print("Lock acquired.")
    with open("myfile.txt"):
        # work with the file as it is now locked


답변

크로스 플랫폼 파일 잠금 모듈이 있습니다 : Portalocker

Kevin이 말했듯이 한 번에 여러 프로세스에서 파일에 쓰는 것은 가능한 한 피하고 싶은 일입니다.

문제를 데이터베이스에 삽입 할 수 있다면 SQLite를 사용할 수 있습니다. 동시 액세스를 지원하고 자체 잠금을 처리합니다.


답변

다른 솔루션은 많은 외부 코드 기반을 인용합니다. 직접 수행하려면 Linux / DOS 시스템에서 해당 파일 잠금 도구를 사용하는 크로스 플랫폼 솔루션에 대한 코드가 있습니다.

try:
    # Posix based file locking (Linux, Ubuntu, MacOS, etc.)
    import fcntl, os
    def lock_file(f):
        fcntl.lockf(f, fcntl.LOCK_EX)
    def unlock_file(f):
        fcntl.lockf(f, fcntl.LOCK_UN)
except ModuleNotFoundError:
    # Windows file locking
    import msvcrt, os
    def file_size(f):
        return os.path.getsize( os.path.realpath(f.name) )
    def lock_file(f):
        msvcrt.locking(f.fileno(), msvcrt.LK_RLCK, file_size(f))
    def unlock_file(f):
        msvcrt.locking(f.fileno(), msvcrt.LK_UNLCK, file_size(f))


# Class for ensuring that all file operations are atomic, treat
# initialization like a standard call to 'open' that happens to be atomic.
# This file opener *must* be used in a "with" block.
class AtomicOpen:
    # Open the file with arguments provided by user. Then acquire
    # a lock on that file object (WARNING: Advisory locking).
    def __init__(self, path, *args, **kwargs):
        # Open the file and acquire a lock on the file before operating
        self.file = open(path,*args, **kwargs)
        # Lock the opened file
        lock_file(self.file)

    # Return the opened file object (knowing a lock has been obtained).
    def __enter__(self, *args, **kwargs): return self.file

    # Unlock the file and close the file object.
    def __exit__(self, exc_type=None, exc_value=None, traceback=None):
        # Flush to make sure all buffered contents are written to file.
        self.file.flush()
        os.fsync(self.file.fileno())
        # Release the lock on the file.
        unlock_file(self.file)
        self.file.close()
        # Handle exceptions that may have come up during execution, by
        # default any exceptions are raised to the user.
        if (exc_type != None): return False
        else:                  return True        

이제 일반적으로 명령문을 사용하는 블록에서 AtomicOpen사용할 수 있습니다 .withopen

경고 : 종료 가 호출 되기 전에 Windows에서 실행 중이고 Python이 충돌 하면 잠금 동작이 무엇인지 잘 모르겠습니다.

경고 : 여기에 제공된 잠금은 절대적인 것이 아니라 권고입니다. 잠재적으로 경쟁중인 모든 프로세스는 “AtomicOpen”클래스를 사용해야합니다.


답변

lockfile을 선호합니다 — 플랫폼 독립적 인 파일 잠금


답변

나는 그것을하기 위해 여러 가지 해결책을 찾고 있으며 내 선택은
오슬로입니다.

강력하고 비교적 잘 문서화되어 있습니다. 패스너를 기반으로합니다.

다른 솔루션 :

  • Portalocker : pywin32가 필요합니다. exe 설치이므로 pip를 통해 사용할 수 없습니다.
  • 패스너 : 제대로 문서화되지 않음
  • lockfile : 사용되지 않습니다
  • flufl.lock : POSIX 시스템을위한 NFS 안전 파일 잠금.
  • simpleflock : 마지막 업데이트 2013-07
  • zc.lockfile : 마지막 업데이트 2016-06 (2017-03 기준)
  • lock_file : 2007-10의 마지막 업데이트

답변

잠금은 플랫폼 및 장치마다 다르지만 일반적으로 몇 가지 옵션이 있습니다.

  1. flock () 또는 이와 동등한 기능을 사용하십시오 (os가 지원하는 경우). 잠금을 확인하지 않으면 무시되는 권고 잠금입니다.
  2. lock-copy-move-unlock 방법론을 사용하십시오. 여기서 파일을 복사하고 새 데이터를 작성한 다음 이동하십시오 (이동, 복사-이동은 Linux의 원자 작업입니다-OS 확인). 잠금 파일의 존재.
  3. 디렉토리를 “잠금”으로 사용하십시오. NFS는 flock ()을 지원하지 않기 때문에 NFS에 쓰는 경우 필요합니다.
  4. 프로세스간에 공유 메모리를 사용할 가능성도 있지만 시도한 적이 없습니다. OS에 따라 다릅니다.

이러한 모든 방법에 대해 잠금을 획득하고 테스트하려면 스핀 잠금 (실패 후 재시도) 기술을 사용해야합니다. 이로 인해 잘못된 동기화를위한 작은 창이 남지만 일반적으로 큰 문제가되지 않을 정도로 작습니다.

플랫폼 간 솔루션을 찾고 있다면 다른 메커니즘을 통해 다른 시스템에 로깅하는 것이 좋습니다 (다음의 가장 좋은 방법은 위의 NFS 기술입니다).

sqlite는 일반 파일의 NFS와 동일한 제약 조건을 따르므로 네트워크 공유의 sqlite 데이터베이스에 쓸 수 없으며 무료로 동기화 할 수 없습니다.


답변

OS 수준에서 단일 파일에 대한 액세스 조정은 해결하고 싶지 않은 모든 종류의 문제로 가득 차 있습니다.

최선의 방법은 해당 파일에 대한 읽기 / 쓰기 액세스를 조정하는 별도의 프로세스입니다.