Python:在NF上锁定文本文件

2024-09-30 10:42:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我在一个服务器上有一个文件results.txt,该文件可由多个vm通过NFS访问。在这些vm上运行一个进程,它读取results.txt文件并对其进行修改。如果两个进程AB同时读取文件,则根据进程写入文件的顺序,results.txt中会出现A或B的修改。在

如果进程A对该文件有写锁,那么进程B必须等到释放锁才能读取results.txt文件。在

我尝试过使用Python实现这一点:

import fcntl


f = open("/path/result.txt")
fcntl.flock(f,fcntl.LOCK_EX)
#code

对于本地磁盘上的文件,它可以正常工作。在

但当我运行try to lock a file on the mounted path时,我得到以下错误:

^{pr2}$

我尝试了fcntl.fcntlfcntl.flock,但得到了相同的错误。这是我使用fcntl的方式有问题吗?在存储文件的服务器上是否需要任何配置?在

编辑:

这是我如何使用fcntl.fcntl

f= open("results.txt")
lockdata = struct.pack('hhllhh', fcntl.F_RDLCK,0,0,0,0,0)
rv = fcntl.fcntl(f, fcntl.F_SETLKW, lockdata)

NFS服务器版本为3。在


Tags: 文件pathimport服务器txt进程顺序错误
1条回答
网友
1楼 · 发布于 2024-09-30 10:42:33

我发现flufl.lock最适合我的要求。在

引用项目page中的作者:

[...] O_EXCL is broken on NFS file systems, programs which rely on it for performing locking tasks will contain a race condition. The solution for performing atomic file locking using a lockfile is to create a unique file on the same fs (e.g., incorporating hostname and pid), use link(2) to make a link to the lockfile. If link() returns 0, the lock is successful. Otherwise, use stat(2) on the unique file to check if its link count has increased to 2, in which case the lock is also successful.

因为它不是标准库的一部分,所以我不能使用它。而且,我的需求只是这个模块提供的所有特性的一个子集。在

以下函数是基于这些模块编写的。请根据要求进行更改。在

def lockfile(target,link,timeout=300):                                             
        global lock_owner                                                          
        poll_time=10                                                               
        while timeout > 0:                                                         
                try:                                                               
                        os.link(target,link)                                       
                        print("Lock acquired")                                      
                        lock_owner=True                                            
                        break                                                      
                except OSError as err:                                             
                        if err.errno == errno.EEXIST:                              
                                print("Lock unavailable. Waiting for 10 seconds...")
                                time.sleep(poll_time)                              
                                timeout-=poll_time                                 
                        else:                                                      
                                raise err                                          
        else:                                                                      
                print("Timed out waiting for the lock.") 

def releaselock(link):                          
        try:                                    
                if lock_owner:                  
                        os.unlink(link)         
                        print("File unlocked")   
        except OSError:                         
                print("Error:didn't possess lock.")

这是一个粗略的实现,对我有用。我一直在使用它,没有遇到任何问题。不过,还有很多事情可以改进。希望这有帮助。在

相关问题 更多 >

    热门问题