레코드 잠금
fcntl() 파일을 제어한다.
int fcntl(int fd,int cmd,struct flock *lock)
struct flock의 l_type멤버
F_RDLCK 읽기잠금을 설정한다.
F_WRLCK 쓰기잠금을 설정한다. 다른 프로세스의 모든 잠금을 막아 다른 프로세스가 파일을 읽고,쓰지 못함
F_UNLCK 잠금을 해제한다.
struct flock의 l_whence멤버, l_start, l_len
SEEK_SET
SEEK_CUR
SEEK_END
------------------------------------------------------------------------------------------------------
a.out 파일을 만들고 잠금
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
main(int argc, char *argv[])
{
int fd;
struct flock filelock;
/* argv[1]의 내용이 “r”이면 F_RDLCK를, 아니면 F_WRLCK를 filelock.l_type에 저장 */
filelock.l_type = (!strcmp(argv[1],"r"))?F_RDLCK:F_WRLCK;
/* 파일 전체를 영역으로 */
filelock.l_whence = SEEK_SET;
filelock.l_start = 0;
filelock.l_len = 0;
/* argv[2] 파일을 여는데 없으면 생성 */
fd = open(argv[2], O_RDWR | O_CREAT, 0666);
/* fd 파일 즉, argv[2]에 대해 filelock 형태로 레코드 잠금을 설정 */
if(fcntl(fd, F_SETLK, &filelock) == -1) {
perror("fcntl failed");
exit(1);
}
printf("locked %s\n", argv[2]);
sleep(30);
printf("unlocked %s\n", argv[2]);
exit(0);
}
b.out
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
main(int argc, char *argv[])
{
int fd;
struct flock filelock;
filelock.l_type = (!strcmp(argv[1],"r"))?F_RDLCK:F_WRLCK;
/* 파일 전체를 영역으로 */
filelock.l_whence = SEEK_SET;
filelock.l_start = 0;
filelock.l_len = 0;
fd = open(argv[2], O_RDWR); /* agrv[2] 파일 열기 */
/* fd 파일에 대해 filelock 형태로 레코드 잠금을 설정. 설정에 실패하면 -1을 반환 */
if(fcntl(fd, F_SETLK, &filelock) == -1) {
perror("fcntl failed");
exit(1);
}
/* 레코드 잠금에 성공하면 실행 */
printf("success\n");
exit(0);
}
[localhost@local]#a.out r file&
locked file
[localhost@local]#b.out r file
success --> 파일 잠금 성공
[localhost@local]#b.out w file 쓰기 시도
잠금시도
fcntl failed : Resource temporaily unavilable
unlocked file
[localhost@local]#a.out w file&
locked file
[localhost@local]#b.out r file 쓰기 시도
잠금시도
fcntl failed : Resource temporaily unavilable
[localhost@local]#b.out w file 쓰기 시도
잠금시도
fcntl failed : Resource temporaily unavilable
unlocked file
--------------------------------------------------------------------------------------------------------
fcntl함수에서 레코드 잠금을 설정하는 cmd값은 F_SETLK와 F_SETLKW 두 가지가 있는데
F_SETLK는 레코드가 다른 프로세스에 의해 이미 잠겨 실패했을 때 실패를 반환하는 반면
F_SETLKW는 성공할때 까지 기다린다
부모프로세스에 의해 쓰기 잠금된 파일에 대해 자식 프로세스가 잠금을 요청했으나 실패하여 레코드 잠금이
해제될 때 까지 기다린다.
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
main(int argc, char *argv[])
{
int fd;
struct flock filelock;
filelock.l_type = F_WRLCK; /* 쓰기 잠금 */
filelock.l_whence = SEEK_SET; /* 파일의 시작을 기준으로 */
filelock.l_start = 0; /* 기준의 처음부터 */
fd = open(argv[1], O_RDWR); /* agrv[1] 파일 열기 */
/* fork에 의해 자식 프로세스를 생성 */
switch(fork()) {
/* fork 호출에 실패하면 */
case -1:
perror("fork failed");
exit(1);
/* 자식 프로세스는 */
case 0:
filelock.l_len = 5; /* 5바이트 크기에 대해 */
/* fd 파일에 대해 레코드 잠금을 설정.
이미 레코드 잠금이 설정되어 있으면 해제될 때까지 기다림 */
if(fcntl(fd, F_SETLKW, &filelock) == -1) {
perror("fcntl failed");
exit(1);
}
printf("child process: locked\n");
sleep(3);
/* 레코드 잠금을 해제 */
filelock.l_type = F_UNLCK;
if(fcntl(fd, F_SETLK, &filelock) == -1) {
perror("fcntl failed");
exit(1);
}
printf("child process: unlocked\n");
break;
/* 부모 프로세스는 */
default:
filelock.l_len = 10; /* 10바이트 크기에 대해 */
/* fd 파일에 대해 레코드 잠금을 설정 */
if(fcntl(fd, F_SETLKW, &filelock) == -1) {
perror("fcntl failed");
exit(1);
}
printf("parent process: locked\n");
sleep(3);
/* 레코드 잠금을 해제 */
filelock.l_type = F_UNLCK;
if(fcntl(fd, F_SETLK, &filelock) == -1) {
perror("fcntl failed");
exit(1);
}
printf("parent process: unlocked\n");
/* 자식 프로세스가 종료될 때까지 기다림 */
wait(NULL);
}
exit(0);
}
[localhost@local]# a.out file
parent process : locked
parend process : unlocked
child process : locked
child process : unlocked
'EMBEDDED > SYSTEM Proc' 카테고리의 다른 글
[Network] popen(), pclose() 함수를 이용한 통신 (0) | 2012.07.13 |
---|---|
[Network] fcntl(), lockf() 예제 2 (0) | 2012.07.13 |
[Signal] sigpending(),sigsuspend() 예제 (0) | 2012.07.13 |
[Signal] sigprocmask() 관련 예제 (0) | 2012.07.13 |
[Signal] raise(), alarm()관련 예제 (0) | 2012.07.13 |