3가지 주요 메커니즘이 존재한다. 모두 제 3의 프로그램이 같이 돌아야 한다는 것이 필요하며, 파일을 공유하는 것에 있어 상당히 주의를 요구한다는 점이 있다.
일부 유닉스에서는 수동적으로 setgid bit를 통한 파일 락이 가능하다.
일부 어플리케이션은 lock 파일 ( filename.lock ) 을 사용한다. 하지만 이 경우에 파일의 존재를 체크할 때는 문제가 있을 수 있다.
UUCP에 의한 방법은 ( 가장 잘 알려진 방법 ) lockfile 에 PID를 저장하는 방식이다. 그리고 PID가 여전히 돌아가고 있는 지 체크하는
방법이다. 이 방법이 그렇게 확실한 방법은 아니다. 왜냐하면, PID는 재사용할 수도 있기 때문이다. 또한 락을 들고 있는 파일을 주기적으로 업데이트 시켜 주어야 한다. 파일 락을 하는 함수들은 다음과 같다.
flock();
lockf();
fcntl();
flock()은 BSD에서 생긴 것이다. 대부분의 유닉스에서 이를 지원한다. 싱글 호스트에서는 매우 쉽고 유효하게 처리 될 수 있는 장점이 있지만, NFS에서는 동작하지 못한다. 모든 파일에 락을 걸기 때문이다.
fcntl() 이 유일한 POSIX 호환성있는 locking 메커니즘이다. 즉, 유일한 이식 체계이다.
또한 강력하기도 하다. 하지만 다루기가 어려운 것이 문제이다. fcntl 은 NFS 마운트된 시스템에 요구를 하여, rpc.lockd 데몬에 넘겨주고, 통신을 개시한다. 또한 flock()과는 다르게 record-level locking 이 가능하다. lockf() 은 fcntl()을 조금 쉽게 쓰기 위한 함수이다.
락을 걸 때는 항상 file I/O을 동기화 시켜주는 것이 필요하다.
lock(fd);
write_to (some_function_of (fd));
flush_output_to(fd);
unlock(fd);
do_something_else;
lock(fd);
seek(fd, somewhere );
do_something_else (fd);
……
유용한 예제는 다음을 참고하자.
#include <fcntl.h>
#include <unistd.h>
read_lock( int fd)
{
fcntl(fd, F_SETLKW, file_lock(F_RDLCK, SEEK_SET ));
}
write_lock( int fd)
{
fcntl(fd, F_SETLKW, file_lock(F_WRLCK, SEEK_SET));
}
append_lock (int fd)
{
fcntl(fd , F_SETLKW, file_lock( F_WRLCK, SEEK_END ));
}
위와 같이 정의된 함수를 이용해서,
struct flock* file_lock( short type, short whence)
{
static struct flock ret;
ret.l_type = type ;
ret.l_start = 0 ;
ret.l_whence = whence ;
ret.l_len = 0;
ret.l_pid = getpid();
return &ret;
}
일부 유닉스에서는 수동적으로 setgid bit를 통한 파일 락이 가능하다.
일부 어플리케이션은 lock 파일 ( filename.lock ) 을 사용한다. 하지만 이 경우에 파일의 존재를 체크할 때는 문제가 있을 수 있다.
UUCP에 의한 방법은 ( 가장 잘 알려진 방법 ) lockfile 에 PID를 저장하는 방식이다. 그리고 PID가 여전히 돌아가고 있는 지 체크하는
방법이다. 이 방법이 그렇게 확실한 방법은 아니다. 왜냐하면, PID는 재사용할 수도 있기 때문이다. 또한 락을 들고 있는 파일을 주기적으로 업데이트 시켜 주어야 한다. 파일 락을 하는 함수들은 다음과 같다.
flock();
lockf();
fcntl();
flock()은 BSD에서 생긴 것이다. 대부분의 유닉스에서 이를 지원한다. 싱글 호스트에서는 매우 쉽고 유효하게 처리 될 수 있는 장점이 있지만, NFS에서는 동작하지 못한다. 모든 파일에 락을 걸기 때문이다.
fcntl() 이 유일한 POSIX 호환성있는 locking 메커니즘이다. 즉, 유일한 이식 체계이다.
또한 강력하기도 하다. 하지만 다루기가 어려운 것이 문제이다. fcntl 은 NFS 마운트된 시스템에 요구를 하여, rpc.lockd 데몬에 넘겨주고, 통신을 개시한다. 또한 flock()과는 다르게 record-level locking 이 가능하다. lockf() 은 fcntl()을 조금 쉽게 쓰기 위한 함수이다.
락을 걸 때는 항상 file I/O을 동기화 시켜주는 것이 필요하다.
lock(fd);
write_to (some_function_of (fd));
flush_output_to(fd);
unlock(fd);
do_something_else;
lock(fd);
seek(fd, somewhere );
do_something_else (fd);
……
유용한 예제는 다음을 참고하자.
#include <fcntl.h>
#include <unistd.h>
read_lock( int fd)
{
fcntl(fd, F_SETLKW, file_lock(F_RDLCK, SEEK_SET ));
}
write_lock( int fd)
{
fcntl(fd, F_SETLKW, file_lock(F_WRLCK, SEEK_SET));
}
append_lock (int fd)
{
fcntl(fd , F_SETLKW, file_lock( F_WRLCK, SEEK_END ));
}
위와 같이 정의된 함수를 이용해서,
struct flock* file_lock( short type, short whence)
{
static struct flock ret;
ret.l_type = type ;
ret.l_start = 0 ;
ret.l_whence = whence ;
ret.l_len = 0;
ret.l_pid = getpid();
return &ret;
}
'Linux' 카테고리의 다른 글
spinlock (0) | 2013.09.26 |
---|---|
spinlock (0) | 2013.09.26 |
IP spoof에 관하여 (0) | 2013.09.26 |
list_entry (0) | 2013.09.26 |
.vimrc config file (0) | 2013.09.26 |