2012-09-21 6 views
0

나는 flock()을 사용하여 리눅스에서 파일을 잠글 수 있다는 것을 알고있다. 그러나 NFS 드라이브는 파일 잠금을 지원하지 않을 수 있습니다.리눅스에서 리눅스 파일 잠김

내 Java 코드에서 일부 사용자 지정 파일 잠금 논리를 구현하여 모든 드라이브에서 파일 잠금을 지원할 생각입니다. 누구든지 좋은 습관을 제안 할 수 있습니까?

감사합니다,

답변

1
만들 수

새로운 당신이 (다음 당신이 자바에서 일부 사용자 지정 파일 잠금 로직을 구현하고 싶다고 언급 한 이후 자바의 예입니다)를 잠금 파일로 사용할 직접 파일 :

File lockFile = new File(".filelock"); 
if(!lockFile.exists()){ 
    //create lock file 
    boolean success = lockFile.createNewFile();  

    //execute some logic... 

    //delete lock file 
    lockFile.delete();         
}else{ 
    //lock file exists, cannot execute the logic that we wanted 
} 
+1

답변 해 주셔서 감사합니다. 나는 그것에 대해 생각했지만, 내 프로세스가 파일을 삭제하지 않고 중간에 나가면. 파일은 영원히 잠깁니다. – Frank

+0

http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#addShutdownHook%28java.lang.Thread%29 –

+0

... if 위와 같이 실패하면 lockfile (파일에 pid 넣기)을 찾은 후 살아있는 프로세스를 확인할 수 있습니다. 찾지 못하면 lockfile을 삭제할지 묻습니다. vim과 emacs가 스왑/백업 파일에서하는 것과 마찬가지입니다. – sapht

2

단일 프로세스의 스레드 간 잠금과 같이 범위가 좁지 않다면 운영 체제 커널/파일 시스템 드라이버가 파일 잠금을 수행해야합니다. 시스템의 다른 모든 프로세스가 응용 프로그램에 잠금/잠금 해제를 요청하기 위해 다시 작성하지 않고 응용 프로그램과 통신 할 수있는 방법은 없습니다. 이것은 NFS가하는 것과 같은 분산 된 로크를 생각할 때 더욱 중요합니다 (비록 잘 수행하지 못하는 많은 깨진 NFS 구현이 있음에도 불구하고).

0

Java 표준 라이브러리는 flock() 또는 fnctl()을 직접 노출하지 않습니다. FileChannel/FileLock에서 lockf()을 사용하는 것 같습니다. 그러나 확신이 필요하면 lockf()을 사용하여 계산하지 않을 것입니다. 라이브러리의 관점에서 이것은 변경할 수있는 구현 세부 사항입니다.

실제로 특정 POSIX 함수를 사용하려면 jnr-posix 및 관련 프로젝트를 살펴보십시오. 다음은 어떻게 사용할 수있는 예입니다. 주의 할 점은 기본적으로 Java에서 저수준 C를 작성하는 것입니다.하지만 이것이 결국 목표입니다. :)

// couldn't find these in jnr-posix... 
// from http://linux.die.net/include/sys/file.h 
/* Operations for the `flock' call. */ 
public static final int LOCK_EX = 2; /* Exclusive lock. */ 
public static final int LOCK_UN = 8; /* Unlock. */ 
/* Can be OR'd in to one of the above. */ 
public static final int LOCK_NB = 4; /* Don't block when locking. */ 

private static void throwErrno(String fn, Path path) throws IOException { 
    int err = posix.errno(); 
    throw new IOException(fn + "() returned errno " + err + " '" + Errno.valueOf(err) + "' for " + path); 
} 

public int flock(Path path, int mode, boolean blocking) { 
    int fd = posix.open(path.toString(), 
     OpenFlags.O_WRONLY.intValue() | OpenFlags.O_CREAT.intValue(), 
     mode); 
    if (fd < 0) { 
     throwErrno("open", path); 
    } 
    int operation = LOCK_EX; 
    if (!blocking) { 
     operation |= LOCK_NB; 
    } 
    int ret = posix.flock(fd, operation); 
    if (ret != 0) { 
     throwErrno("flock", path); 
    } 
    return fd; 
} 

이것은 단지 최소한의 데모 코드입니다. 닫을 때 로그를 해제하는 AutoClosable을 반환하는 것이 좋습니다.