multipel reader, single writer일 경우 사용
- 록 정보는 fork 호출에 의해 계승되지 않음
- fcntl 호출의 파일 포인터를 변경시키지 않음
- 한 프로세스에 속한 모든 록은 그 프로세스 죽을 때 자동 제거됨
- 읽기 록 : 쓰기만 제한
- 다른 프로세스들이 쓰기 록 적용 못하게 함, 여러 프로세스들이 같은 구역에 동시 읽기 록 가능
- 쓰기 록 : 읽기, 쓰기 다 제한하고 혼자 쓰기만 가능
- 다른 프로세스들이 그 구역에 읽거나 쓰기 록 할 수 없도록 함
- 파일의 한 구역에는 한 순간에 하나의 쓰기 록만이 존재 가능
#include <fcntl.h>
int fcntl(int fildes, int cmd, struct flock *ldata);
int main(){
struct flock my_lock;
my_lock.l_type = F_WRLCK;
my_lock.l_whence = SEEK_CUR;
my_lock.l_start = 0;
my_lock.l_len = 512;
fcntl(fd, F_SETLKW, &my_lock);
//F_GETLK : 잠금 검사
//F_SETLK : 잠금설정(블로킹 버전) or 해제
}
- fildes : 유효한 개방된 파일 기술자
- 읽기 록인 경우 O_RDONLY나 O_RDWR로 개방 (O_RDONLY|O_RDWR)
- 쓰기 록을 위해서는 O_WRONLY나 O_RDWR로 개방 (O_WRONLY|O_RDWR)
- cmd
- F_GETLK : ldata를 통해 전달된 록 정보 획득
- F_SETLK : 파일에 록 적용, 불가능하면 즉시 -1로 돌아옴
- F_SETLKW : 파일에 록 적용, 이것이 만약 다른 프로세스가 소유하고 있다면 수면함 (blocking)
- ldata
- short l_type; - 록의 유형
shrot l_whence; - lseek와 동일
off_t l_start; - 바이트로 표시된 offset (whence부터 상대적 위치로 시작번지)
off_t l_len; - 바이트 단위의 세그먼트 크기 (록 크기)
pid_t l_pid; - 명령에 의해 설정됨 ex) flag가 F_GETLK인 경우 이미 록 설정한 process만 id 정보 가짐 - F_RDLCK : 읽기 록 전용 (여러 프로세스 동시 읽기 가능)
- F_WRLCK : 쓰기 록 전용 (여러 프로세스 시도 시 맨 처음 1개만 쓰기 가능)
- F_UNLCK : 록 제거
- short l_type; - 록의 유형
main() {
int fd;
struct flock my_lock;
struct flock b_lock;
my_lock.l_type = F_WRLCK; //쓰기록
my_lock.l_whence = SEEK_SET; //처음부터
my_lock.l_start = 0; //offset이 0
my_lock.l_len = 10; //록 크기 10
fd = open("testdata", O_RDWR);
fcntl(fd, F_SETLKW, &my_lock); //파일에 록 적용
printf("parent : locked record\n");
switch(fork()) {
case -1 :
perror("fork");
exit(1);
case 0 :
my_lock.l_len = 5;
if (fcntl(fd, F_SETLKW, &my_lock) == -1) { //파일에 록 적용
perror("child : locking");
exit(1);
}
printf("child: locked\n");
printf("child: exiting\n");
exit(0);
}
sleep(2);
printf("parent: unlocking\n");
my_lock.l_type = F_UNLCK;
fcntl(fd, F_SETLK, &my_lock); //록 해제 적용
exit(0);
}