Download presentation
Presentation is loading. Please wait.
1
Linux System Programming
Lecture #4 – 파일과 레코드 록킹
2
레코드 록킹 (1) 레코드 록킹(Record Locking) 레코드 록킹의 필요성
두 개 이상의 프로세스가 하나의 파일 데이터(레코드)를 동시에 접근하지 못하도록 제어하는 것 프로세스가 자신의 배타적인 사용을 위해 파일의 일부를 임시로 보존할 수 있게 하여 데이터베이스 관리 등에서 발생하는 문제를 해결하도록 지원 레코드 록킹의 필요성 예: 기차표 예약 시스템 이유: 여러 개의 프로세스가 동시에 linux 파일을 접근하여 파일 쓰기 연산이 가능하기 때문 해결책: 프로세스가 현재 사용중인 파일의 일부를 로킹하여 다른 프로세스가 그 데이터를 접근할 수 없도록 지원 Linux System Programming
3
레코드 록킹 (2) 레코드 록킹 연산 하나의 프로세스가 공유 파일에 쓰기 위해 파일의 일부를 록킹(locking)한다
록킹된 파일 부분을 레코드라고 함 파일 쓰기를 수행하고 레코드 록킹을 해제한다 파일이 록킹되어 있는 동안 다른 프로세스는 록킹된 레코드에 쓰기 연산을 수행할 수 없다 레코드 록킹 연산은 원자적으로(atomic) 수행된다 레코드 록킹 연산을 수행동안 프로그램 수행이 중지되지 않음을 의미 Linux System Programming
4
레코드 록킹 (3) 레코드 록킹 시스템 호출 fcntl() lockf() 최초의 레코드 록킹 시스템 호출
유닉스 사용자 그룹의 표준 위원회에 의해 채택 fcntl() AT&T의 System-V 버전에서 지원 lockf() 보다 더 일반적인 형태의 레코드 록킹을 수행 Linux System Programming
5
fcntl() 시스템 호출 (1) fcntl() 시스템 호출 파일 제어 호출 함수 2가지 형태의 레코드 록킹을 제공
파일의 기본적인 연산(읽기, 쓰기) 이외의 추가적인 파일 제어 연산을 제공하는 시스템 호출 레코드 록킹 제어 연산을 지원 2가지 형태의 레코드 록킹을 제공 읽기 록킹 록킹된 구역(segment)에 대해 읽기 연산은 가능하나 쓰기 연산을 허용하지 않는 록킹 연산 여러 프로세스가 같은 구역에 대해 동기에 읽기 록킹이 가능 쓰기 록킹 록킹된 구역(segment)에 대해 다른 프로세스의 읽기 및 쓰기 연산을 허용하지 않는 록킹 연산 파일의 한 구역에 대해서는 단지 하나의 쓰기 록킹만 가능 Linux System Programming
6
fcntl() 시스템 호출 (2) fcntl() 시스템 호출 Linux System Programming
7
fcntl() 시스템 호출 (3) fcntl() 시스템 호출 레코드 록킹 명령 Linux System Programming
8
fcntl() 시스템 호출 (4) fcntl() 시스템 호출 레코드 록킹 명령의 파라미터 :
#include <fcntl.h> struct flock { short l_type; // 레코드 록킹 유형 short l_where; // lseek와 같음 long l_start; // 잠금 영역의 시작 위치 long l_len; // 잠금영역의 크기 short l_sysid; // F_GETLK에서 유효 shoprt l_pid; // F_GETLK에서 유효 }; Linux System Programming
9
fcntl() 시스템 호출 (5) 예제 프로그램 4-2:
vi로 파일을 편집하는 동안에 다른 사용자가 편집중인 파일에 접근하지 못하도록 lock시키는 프로그램 작성 #include <fcntl.h> #include <errno.h> main(argc, argv) int argc; char *argv[]; { struct flock lock; int fd, open(), fcntl(); char command[100]; if ((fd = open(argv[1], O_RDWR)) == -1) { perror(argv[1]); exit(1); } Linux System Programming
10
fcntl() 시스템 호출 (6) lock.l_type = F_WRLCK; lock.l_whence = 0;
lock.l_start = 0L; lock.l_len = 0L; /* whole file address space */ if (fcntl (fd, F_SETLK, &lock) == -1) { if (errno == EACCES) { printf("%s busy -- try later\n", argv[1]); exit(2); } perror(argv[1]); exit(3); sprintf(command, "vi %s\n", argv[1]); system(command); lock.l_type = F_UNLCK; /* unlock file */ fcntl(fd, F_SETLK, &lock); close(fd); Linux System Programming
11
fcntl() 시스템 호출 (7) 예제 프로그램 4-3:
예제 2-3의 employee 레코드를 수정하는 프로그램 작성하되, 레코드를 읽기 전에 lock하고 수정한 후에 unlock하도록 한다. #include <fcntl.h> #include "ex2-3.h" main(argc, argv) int argc; char *argv[]; { struct flock lock; struct employee record; int fd, open(), pid, getpid(), recnum; long position; if((fd = open(argv[1], O_RDWR)) == -1) { perror(argv[1]); exit(1); } Linux System Programming
12
fcntl() 시스템 호출 (8) pid = getpid(); for(;;) {
printf("\nEnter record number: "); scanf("%d",&recnum); if(recnum < 0) break; position = recnum * sizeof(record); lock.l_type = F_WRLCK; /* lock record */ lock.l_whence = 0; lock.l_start = position; lock.l_len = sizeof(record); if(fcntl(fd, F_SETLKW, &lock) == -1) { perror(argv[1]); exit(2); } lseek(fd, position, 0); /*read record */ if(read(fd, (char *) &record,sizeof(record)) == 0) { printf("record %d not found\n",recnum); lock.l_type = F_UNLCK; fcntl(fd, F_SETLK, &lock); continue; Linux System Programming
13
fcntl() 시스템 호출 (9) printf("Employee: %s, salary: %d\n", record.name, record.salary); record.pid = pid; /* update record */ printf("Enter new salary: "); scanf("%d", &record.salary); lseek(fd, position, 0); write(fd, (char *) &record, sizeof(record)); lock.l_type = F_UNLCK; /* release record */ fcntl(fd, F_SETLK, &lock); } close(fd); Linux System Programming
14
lockf() 시스템 호출 (1) lockf() 시스템 호출 단순하면서 직접적인 레코드 록킹 시스템 호출
배타적인 록킹 연산만을 지원 fcntl() 시스템 호출의 F_WRLCK(쓰기 록킹)과 같다 다른 프로세스가 록킹된 영역을 접근하면 록킹이 해제될 때까지 수면상태(sleep)가 된다 현재는 권고형(advisory) 시스템 호출임. Linux System Programming
15
lockf() 시스템 호출 (2) lockf() 시스템 호출 Linux System Programming
16
lockf() 시스템 호출 (3) lockf() 시스템 호출 lockf() 시스템 호출의 매개 변수
Linux System Programming
17
lockf() 시스템 호출 (4) 예제 프로그램 4-7 예제 4-3 프로그램은 lockf() 시스템 호출을 이용하여 구현하여라
#include <fcntl.h> #include <unistd.h> #include "ex2-3.h" main(argc, argv) int argc; char *argv[]; { struct employee record; struct flock lock; int fd, open(), pid, getpid(), recnum; long position; if((fd = open(argv[1], O_RDWR)) == -1) { perror(argv[1]); exit(1); } Linux System Programming
18
lockf() 시스템 호출 (5) pid = getpid(); for(;;) {
printf("\nEnter record number: "); scanf("%d",&recnum); if(recnum < 0) break; position = recnum * sizeof(record); lseek(fd,position, 0); if(lockf(fd, F_LOCK, sizeof(record)) == -1) { perror(argv[1]); exit(2); } if(read(fd, (char *) &record,sizeof(record)) == 0) { printf("record %d not found\n",recnum); lockf(fd,F_UNLCK, sizeof(record)); continue; Linux System Programming
19
lockf() 시스템 호출 (6) printf("Employee: %s, salary: %d\n", record.name, record.salary); record.pid = pid; /* update record */ printf("Enter new salary: "); scanf("%d", &record.salary); lseek(fd, position, 0); write(fd, (char *) &record, sizeof(record)); lockf(fd, F_UNLCK, sizeof(record)); } close(fd); Linux System Programming
Similar presentations