파이썬으로 작성하려면 파일을 잠 가야합니다. 여러 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
사용할 수 있습니다 .with
open
경고 : 종료 가 호출 되기 전에 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의 마지막 업데이트
답변
잠금은 플랫폼 및 장치마다 다르지만 일반적으로 몇 가지 옵션이 있습니다.
- flock () 또는 이와 동등한 기능을 사용하십시오 (os가 지원하는 경우). 잠금을 확인하지 않으면 무시되는 권고 잠금입니다.
- lock-copy-move-unlock 방법론을 사용하십시오. 여기서 파일을 복사하고 새 데이터를 작성한 다음 이동하십시오 (이동, 복사-이동은 Linux의 원자 작업입니다-OS 확인). 잠금 파일의 존재.
- 디렉토리를 “잠금”으로 사용하십시오. NFS는 flock ()을 지원하지 않기 때문에 NFS에 쓰는 경우 필요합니다.
- 프로세스간에 공유 메모리를 사용할 가능성도 있지만 시도한 적이 없습니다. OS에 따라 다릅니다.
이러한 모든 방법에 대해 잠금을 획득하고 테스트하려면 스핀 잠금 (실패 후 재시도) 기술을 사용해야합니다. 이로 인해 잘못된 동기화를위한 작은 창이 남지만 일반적으로 큰 문제가되지 않을 정도로 작습니다.
플랫폼 간 솔루션을 찾고 있다면 다른 메커니즘을 통해 다른 시스템에 로깅하는 것이 좋습니다 (다음의 가장 좋은 방법은 위의 NFS 기술입니다).
sqlite는 일반 파일의 NFS와 동일한 제약 조건을 따르므로 네트워크 공유의 sqlite 데이터베이스에 쓸 수 없으며 무료로 동기화 할 수 없습니다.
답변
OS 수준에서 단일 파일에 대한 액세스 조정은 해결하고 싶지 않은 모든 종류의 문제로 가득 차 있습니다.
최선의 방법은 해당 파일에 대한 읽기 / 쓰기 액세스를 조정하는 별도의 프로세스입니다.