我需要鎖定一個文件以用Python編寫。它將一次從多個Python進程訪問。我在網上找到了一些解決方案,但是大多數解決方案都失敗了,因爲它們通常只有基於Unix或Windows。在Python中鎖定文件
回答
好了,所以我最終的代碼要我寫
here, on my website
link is dead, view on archive.org(also available on GitHub)。我可以通過以下方式使用它:
from filelock import FileLock
with FileLock("myfile.txt"):
# work with the file as it is now locked
print("Lock acquired.")
鎖定文件通常是特定於平臺的操作,因此您可能需要考慮在不同操作系統上運行的可能性。例如:
import os
def my_lock(f):
if os.name == "posix":
# Unix or OS X specific locking here
elif os.name == "nt":
# Windows specific locking here
else:
print "Unknown operating system, lock unavailable"
協調對操作系統級別的單個文件的訪問充滿了各種您可能不想解決的問題。
你最好打賭的是有一個單獨的進程,協調對該文件的讀/寫訪問。
」單獨的進程,座標讀取/寫入訪問該文件「 - 換句話說,實現數據庫服務器:-) – 2009-01-31 08:39:10
這實際上是最好的答案。僅僅說「使用數據庫服務器」就過於簡單了,因爲db並不總是成爲正確的工具。如果它需要是純文本文件呢?一個好的解決方案可能是產生一個子進程,然後通過命名管道,unix套接字或共享內存訪問它。 – 2011-07-22 04:55:24
-1因爲這只是FUD而沒有解釋。鎖定一個文件以供寫入對我來說似乎是一個非常簡單的概念,操作系統提供了像``flock`](http://linux.die.net/man/2/flock)這樣的函數。 「滾動自己的互斥體和守護進程來管理它們」似乎是一種相當極端和複雜的方法來解決......一個你實際上沒有告訴我們的問題,但只是存在一些可疑的暗示。 – 2016-05-10 11:38:28
有一個跨平臺的文件鎖定模塊的位置:Portalocker
雖然凱文說,寫從多個進程同時文件是你想避免,如果在所有可能的東西。
如果您可以將您的問題解決到數據庫中,則可以使用SQLite。它支持併發訪問並處理自己的鎖定。
鎖定是平臺和特定的設備,但通常,你有幾種選擇:
- 用羊羣(),或equivilent(如果您的操作系統支持)。這是建議性鎖定,除非您檢查鎖定,否則將其忽略。
- 使用鎖複製移動解鎖方法,您可以在其中複製文件,寫入新數據,然後移動它(移動,而不是複製 - 移動是Linux中的原子操作 - 檢查您的操作系統),而您檢查鎖定文件的存在。
- 使用一個目錄作爲「鎖」。如果你正在寫入NFS,這是必須的,因爲NFS不支持flock()。
- 也有可能在進程之間使用共享內存,但我從來沒有嘗試過;它非常特定於操作系統。
對於所有這些方法,您必須使用自旋鎖定(故障後重試)技術來獲取和測試鎖定。這確實給失步留下了一個小窗口,但它通常足夠小,不會成爲主要問題。
如果你正在尋找一個跨平臺的解決方案,那麼你最好通過其他機制登錄到另一個系統(其次最好的是上面的NFS技術)。
請注意,sqlite受到與普通文件相同的NFS約束,因此您無法寫入網絡共享上的sqlite數據庫並獲得免費的同步。
我喜歡lockfile - 平臺無關的文件鎖定
我發現了一個簡單的工作(!)來自grizzled-python的implementation。
簡單使用os.open(...,O_EXCL)+ os.close()在windows上不起作用。
我一直在努力處理這種情況,我在同一目錄/文件夾中運行同一程序的多個副本並記錄錯誤。我的方法是在打開日誌文件之前寫入「鎖定文件」到光盤。程序在繼續之前檢查是否存在「鎖定文件」,如果存在「鎖定文件」,則等待它。
這裏是代碼:「鎖定文件」
def errlogger(error):
while True:
if not exists('errloglock'):
lock = open('errloglock', 'w')
if exists('errorlog'): log = open('errorlog', 'a')
else: log = open('errorlog', 'w')
log.write(str(datetime.utcnow())[0:-7] + ' ' + error + '\n')
log.close()
remove('errloglock')
return
else:
check = stat('errloglock')
if time() - check.st_ctime > 0.01: remove('errloglock')
print('waiting my turn')
編輯--- 思考過一些關於陳舊的鎖的意見,上述我編輯的代碼中添加一個檢查爲的陳舊程度後時序我的系統上這個函數的幾個萬次都給並從之前平均0.002066 ...秒:
lock = open('errloglock', 'w')
只是後:
remove('errloglock')
所以我想我會用5次啓動這個數字表明過時並監測問題的情況。
而且,我是用時間的工作,我意識到,我有一些代碼,這是不是真的有必要:
lock.close()
,我曾緊隨公開聲明,所以我已刪除了它在這個編輯中。
我一直在尋找多種解決方案做到這一點,我選擇一直 oslo.concurrency
它的強大和相對有據可查。它基於緊固件。
其他的解決方案:
- Portalocker:需要pywin32,這是一個exe安裝,所以無法通過PIP
- fasteners:記錄不
- lockfile:棄用
- flufl.lock:NFS安全文件鎖定POSIX系統。
- simpleflock:最後更新2013年7月
- zc.lockfile:更新2016-06(截至2017-03)
- lock_file:在2007-10
最新更新你會發現pylocker非常有用。它可以用來鎖定一個文件或鎖定機制,可以一次從多個Python進程訪問。
如果您只是想鎖定文件,這裏是它的工作原理是:
import uuid
from pylocker import Locker
# create a unique lock pass. This can be any string.
lpass = str(uuid.uuid1())
# create locker instance.
FL = Locker(filePath='myfile.txt', lockPass=lpass, mode='w')
# aquire the lock
with FL as r:
# get the result
acquired, code, fd = r
# check if aquired.
if fd is not None:
print fd
fd.write("I have succesfuly aquired the lock !")
# no need to release anything or to close the file descriptor,
# with statement takes care of that. let's print fd and verify that.
print fd
的場景是這樣的: 用戶請求的文件做一些事情。然後,如果用戶再次發送相同的請求,它會通知用戶第二個請求沒有完成,直到第一個請求結束。這就是爲什麼我使用鎖定機制來處理這個問題。
這是我工作的代碼:
from lockfile import LockFile
lock = LockFile(lock_file_path)
status = ""
if not lock.is_locked():
lock.acquire()
status = lock.path + ' is locked.'
print status
else:
status = lock.path + " is already locked."
print status
return status
其他的解決方案列舉了大量的外部代碼庫。如果您更願意自己動手,那麼下面是一些跨平臺解決方案的代碼,它使用Linux/DOS系統上各自的文件鎖定工具。
try:
# Posix based file locking (Linux, Ubuntu, MacOS, etc.)
import fcntl
def lock_file(f):
fcntl.lockf(f, fcntl.LOCK_EX)
def unlock_file(f): pass
except ModuleNotFoundError:
# Windows file locking
import msvcrt
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
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
# Allows users to use the 'close' function if they want, in case
# the user did not have the AtomicOpen in a "with" block.
def close(self): self.__exit__()
# Unlock the file and close the file object
def __exit__(self, exc_type=None, exc_value=None, traceback=None):
# 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」可用於任何通常使用「open」語句的地方。
警告:如果在Windows和Python上運行退出之前崩潰被調用,我不確定鎖定行爲是什麼。
警告:此處提供的鎖定是建議性的,不是絕對的。所有潛在的競爭進程必須使用「AtomicOpen」類。
- 1. 在AccuRev中鎖定文件
- 2. 在.NET中鎖定文件
- 3. 在Python中鎖定方法?
- 4. 在python中鎖定字典
- 5. Python:檢查文件被鎖定
- 6. 用python鎖定一個txt文件
- 7. 更改python-gnupg鎖定文件位置?
- 8. 文件鎖定在PHP
- 9. 如何在C中鎖定文件夾#
- 10. 在PHP中鎖定NFS文件
- 11. 如何在Actionscript中鎖定文件?
- 12. 在PowerShell中寫入時鎖定文件
- 13. 如何在PHP中鎖定文件?
- 14. 在Xcode 4中鎖定文件
- 15. 在Java中鎖定Linux文件
- 16. CDO CreateMHTMLBody在JScript中鎖定文件
- 17. 在Qt中釋放文件鎖定
- 18. Windows C++在內存中鎖定文件
- 19. FileInfo鎖定文件!
- 20. HttpPostedFileBase鎖定文件
- 21. Java文件鎖定
- 22. PowerShell鎖定文件
- 23. Linux文件鎖定
- 24. System.Reflection.Assembly.LoadFile鎖定文件
- 25. 鎖定XML文件
- 26. System.IO.File.Create鎖定文件
- 27. 如何使Windows文件鎖定更像UNIX文件鎖定?
- 28. 刪除用戶在perforce中解鎖所有鎖定的文件
- 29. 在Subversion中遠程鎖定/解鎖文件
- 30. 在Ubuntu中使用C API鎖定和解鎖文件LInux
您可能已經知道這一點,但平臺模塊也可用於獲取有關運行平臺的信息。 platform.system()。 http://docs.python.org/library/platform.html。 「 – monkut 2009-01-29 00:54:14