2016-06-04 27 views
4

NFS를 통해 여러 VM이 액세스하는 서버에 results.txt 파일이 있습니다. 각 VM에서 프로세스가 실행되어 results.txt 파일을 읽고 수정합니다. AB의 두 프로세스가 동시에 파일을 읽으면 프로세스가 파일에 쓰는 순서에 따라 results.txt에 A 또는 B 수정이 나타납니다.Python : NFS에서 텍스트 파일 잠그기

프로세스 A에 파일에 대한 쓰기 잠금이있는 경우 B 프로세스는 잠금이 해제 될 때까지 대기하여 results.txt 파일을 읽어야합니다. 나는이 사용하는 파이썬을 구현하는 시도

:

로컬 디스크에있는 파일에 대해 예상대로 작동
import fcntl 


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

. 내가 fcntl.fcntlfcntl.flock을 시도했지만 같은 오류가 발생했습니다

Traceback (most recent call last): 
    File "lock.py", line 12, in <module> 
    fcntl.flock(f,fcntl.LOCK_EX) 
IOError: [Errno 45] Operation not supported 

: 나는 탑재 된 경로에서 파일을 잠금을 시도 실행할 때

하지만, 나는 다음과 같은 오류가 발생합니다. 이것이 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 서버 버전은 내 요구 사항에 대한 flufl.lock이 가장 적합한 발견 3.

+0

'fcntl.fcntl()'을 사용하는 방법을 붙여 줄 수 있습니까? – vmonteco

+0

@vmonteco, 코드 스 니펫을 추가했습니다. – SilentMonk

+0

'fcntl.fcntl (f, fcntl.LOCK_EX)'가 작동합니까? – vmonteco

답변

2

입니다.

프로젝트 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:did't possess lock") 

이것은 저에게 적합합니다. 나는 그것을 사용하고 어떤 문제에 직면하지 않았습니다. 그러나 개선 할 수있는 많은 것들이 있습니다. 희망이 도움이됩니다.