6장 파일 및 레코드 잠금.

Slides:



Advertisements
Similar presentations
C 프로그래밍 기초.
Advertisements

6 레이스 컨디션.
13장 소켓.
Chapter 10– 표준 함수(1) Outline 10.1 스트림과 파일 10.2 입출력 표준 함수
Linux System Programming
제2부 시스템 프로그래밍 파일 및 입출력 2011 가을 숙명여대 창병모 © 숙대 창병모.
Department of Computer Engineering
Signal & Inter-Process Communication
Linux System Programming
제3장 추가 실습 3장 관련 C 언어 프로그래밍 실습.
Department of Computer Engineering
제2장. 파일 입출력 (File I/O) © 숙대 창병모.
Network Lab. Seoung Hyeon, Lee
6 프로세스 생성과 실행.
Linux System Programming
쉽게 풀어쓴 C언어 Express 제16장 파일 입출력 C Express Slide 1 (of 23)
HW#1 Source 파일 제출 3.20(수)까지 제출 학번_이름_01.c
Part 14 파일 입출력 ©우균, 창병모 ©우균, 창병모.
14장 소켓.
제 12장 I/O멀티플렉싱(Multiplexing)
FND (Flexible Numeric Display)
10장 메모리 관리.
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express.
Department of Computer Engineering
동적메모리와 연결리스트 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
Department of Computer Engineering
12장 파이프.
fork로 생성한 자식 프로세스에서 exec 함수군을 호출
레이스 컨디션 컴퓨터공학과 4학년 이교욱.
9장 파일 입출력.
Term Project Team Member
시스템 호출 read , write의 효율성 lseek test example – test1.c 실습 – 연습문제 2.8
파이프와 exec 시스템 호출 (ls | wc)
파일 기술자 복사 파일 기술자 복사 : dup(2) 파일 기술자 복사 : dup2(3)
12장 파일처리와 매크로 파일 입출력 함수 문자 입출력 함수 라인 입출력 함수 불록 입출력 함수 매크로.
8 메모리 매핑.
Advanced Socket Programming
(ioctl, mmap, fsync&flush)
4장 파일.
11장 파일.
Chapter 4. 보조자료 - 파일 입출력 파일의 기본 개념과 특징을 이해한다. 파일 처리 과정을 이해한다.
Department of Computer Engineering
14주차.
FILE I/O 번째주 Dept. of Computer Science & Engineering
10장 C 표준 파일 입출력 子曰 學而時習(실습?)之 不亦悅乎.
쉽게 풀어쓴 C언어 Express 제7장 반복문 C Express.
5 프로세스 정보.
2장 표준 입출력 표준 입출력 함수의 종류 형식화된 입출력 문자 입출력 문자열 입출력.
Signal & Inter-Process Communication
13장 프로세스 사이의 통신.
Memory & Data Management.
컴퓨터 프로그래밍 기초 - 4th : 수식과 연산자 -
제어문 & 반복문 C스터디 2주차.
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
Stepper Motor 디바이스 드라이버
조 병 규 Software Quality Lab. 한국교통대학교
Chapter 05. 입출력 함수.
실습과제 1(조건문, ) 표준입력으로 수축기 혈압을 입력 받아 그에 따른 적당한 표현을 화면에 출력하는 프로그램을 if-else 문을 이용하여 작성.
#1 배열 활용 #include int main(void) { int i; int grade[5]; grade[0] = 10; grade[1] = 20; grade[2] = 30; grade[3] = 40; grade[4] = 50; for(i=0;i.
Department of Computer Engineering
Execution with Unnecessary Privileges
쉽게 풀어쓴 C언어 Express 제6장 조건문 C Express.
실습과제 1번 생성된 파일 basic.txt를 프로젝트 폴더에서 메모장으로 열고 내용을 확인
argc, argv 의 사용방법 #include <stdio.h>
Signal & Inter-Process Communication
C 13장. 입출력 라이브러리 #include <stdio.h> int main(void) { int num;
어서와 C언어는 처음이지 제22장.
3장 파일 다루기 한빛미디어(주).
개정판 누구나 즐기는 C언어 콘서트 제12장 파일 입출력 출처: pixabay.
Presentation transcript:

6장 파일 및 레코드 잠금

6.1 파일 및 레코드 잠금

파일 및 레코드 잠금의 원리 어떻게 프로세스 사이에 데이터를 주고받을 수 있을까? 문제점 한 프로세스가 파일에 쓴 내용을 다른 프로세스가 읽음 문제점 한 프로세스가 파일 내용을 수정하는 동안에 다른 프로세스가 그 파일을 읽는 경우 두 개의 프로세스가 하나의 파일에 동시에 접근하여 데이터를 쓰 는 경우

잠금(lock) 파일 혹은 레코드(파일의 일부 영역) 잠금 한 프로세스가 그 영역을 읽거나 수정할 때 다른 프로세스의 접근 을 제한 잠금된 영역에 한 번에 하나의 프로세스만 접근 특히 레코드에 쓰기(혹은 수정)를 할 경우 대상 레코드에 대해 잠 금을 해서 다른 프로세스가 접근하지 못하게 해야 한다.

잠금이 필요한 예 잠금 없음 잠금 사용 (1) 프로세스 A가 잔액을 읽는다: 잔액 100만원 잠금이 필요한 예 잠금 없음 (1) 프로세스 A가 잔액을 읽는다: 잔액 100만원 (2) 프로세스 B가 잔액을 읽는다: 잔액 100만원 (3) 프로세스 B가 잔액에 입금액을 더하여 레코드를 수정한다: 잔액 120만원 (4) 프로세스 A가 잔액에 입금액을 더하여 레코드를 수정한다: 잔액 110만원 잠금 사용 (1) 프로세스 A가 레코드에 잠금을 하고 잔액을 읽는다: 잔액 100만원 (2) 프로세스 A가 잔액에 입금액을 더하여 레코드를 수정하고 잠금 을 푼다: 잔액 110만원 (3) 프로세스 B가 레코드에 잠금을 하고 잔액을 읽는다: 잔액 110만원 (4) 프로세스 B가 잔액에 입금액을 더하여 레코드를 수정하고 잠금 을 푼다: 잔액 130만원

잠금 구현 fcntl( ) 함수 잠금의 종류 파일 및 레코드 잠금을 구현할 수 있다. F_RDLCK : 여러 프로세스가 공유 가능한 읽기 잠금 F_WRLCK : 한 프로세스만 가질 수 있는 배타적인 쓰기 잠금 대상 영역의 현재 잠금 상태 읽기 잠금 요청 쓰기 잠금 요청 잠금 없음 승인 하나 이상의 읽기 잠금 거절 하나의 쓰기 잠금

잠금 함수: fcntl() fd는 대상이 되는 파일 디스크립터 cmd flock 구조체 F_GETLK : 잠금 검사 F_SETLK : 잠금 설정 혹은 해제 F_SETLKW: 잠금 설정(블로킹 버전) 혹은 해제 flock 구조체 잠금 종류, 프로세스 ID, 잠금 위치 등 #include <sys/types.h> #include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd, struct flock *lock); cmd에 따라 잠금 검사 혹은 잠금 설정을 한다. 성공하면 0 실패하면 -1을 리턴

flock 구조체 struct flock { short l_type; // 잠금 종류: F_RDLCK, F_WRLCK, F_UNLCK off_t l_start; // 잠금 시작 위치: 바이트 오프셋 short l_whence; // 기준 위치: SEEK_SET, SEEK_CUR, SEEK_END off_t l_len; // 잠금 길이: 바이트 수 (0이면 파일끝까지) pid_t l_pid; // 프로세스 번호 };

6.2 잠금 예제 및 잠금 함수

잠금 예제 학생 레코드를 질의하는 프로그램: rdlock.c 학생 레코드를 수정하는 프로그램: wrlock.c 수정 프로그램에서 어떤 레코드를 수정하는 중에는 질의 프로그램에 서 그 레코드를 읽을 수 없도록 레코드 잠금을 이용하여 제한한다.

rdlock.c 검색할 학번을 입력받는다. 해당 레코드를 읽기 전에 그 레코드에 대해 읽기 잠금 (F_RDLCK)을 한다. fcntl(fd,F_SETLKW, &lock); 해당 레코드 영역에 대해 잠금을 한 후에 레코드를 읽는다.

rdlock.c 1 #include <stdio.h> 2 #include <fcntl.h> 3 #include "student.h" 4 #define START_ID 1201001 5 6 /* 잠금을 이용한 학생 데이터베이스 질의 프로그램 */ 7 int main(int argc, char *argv[]) 8 { 9 int fd, id; 10 struct student record; 11 struct flock lock; 12 13 if (argc < 2) { 14 fprintf(stderr, "사용법 : %s 파일\n", argv[0]); 15 exit(1); 16 }

rdlock.c 18 if ((fd = open(argv[1], O_RDONLY)) == -1) { 19 perror(argv[1]); 20 exit(2); 21 } 22 23 printf("\n검색할 학생의 학번 입력:"); 24 while (scanf("%d", &id) == 1) { 25 lock.l_type = F_RDLCK; 26 lock.l_whence = SEEK_SET; 27 lock.l_start = (id-START_ID)*sizeof(record); 28 lock.l_len = sizeof(record); 29 if (fcntl(fd,F_SETLKW, &lock) == -1) { /* 읽기 잠금 */ 30 perror(argv[1]); 31 exit(3); 32 } 33

rdlock.c 34 lseek(fd, (id-START_ID)*sizeof(record), SEEK_SET); 35 if ((read(fd, (char *) &record, sizeof(record)) > 0) && (record.id != 0)) 37 printf("이름:%s\t 학번:%d\t 점수:%d\n", record.name, record.id, 38 record.score); 39 else printf("레코드 %d 없음\n", id); 40 41 lock.l_type = F_UNLCK; 42 fcntl(fd,F_SETLK, &lock); /* 잠금 해제 */ 43 printf("\n검색할 학생의 학번 입력:"); 44 } 45 46 close(fd); 47 exit(0); 48 }

wrlock.c 수정할 학번을 입력받는다. 해당 레코드를 읽기 전에 그 레코드에 쓰기 잠금(F_WRLCK)을 한다. fcntl(fd,F_SETLKW, &lock); 해당 레코드 영역에 대해 잠금을 한 후에 레코드를 수정한다.

wrlock.c 1 #include <stdio.h> 2 #include <fcntl.h> 3 #include "student.h" 4 #define START_ID 1201001 5 6 /* 잠금을 이용한 학생 데이터베이스 수정 프로그램 */ 7 int main(int argc, char *argv[]) 8 { 9 int fd, id; 10 struct student record; 11 struct flock lock; 12 13 if (argc < 2) { 14 fprintf(stderr, "사용법 : %s 파일 \n", argv[0]); 15 exit(1); 16 } 17

wrlock.c 18 if ((fd = open(argv[1], O_RDWR)) == -1) { 19 perror(argv[1]); 20 exit(2); 21 } 22 23 printf("\n수정할 학생의 학번 입력:"); 24 while (scanf("%d", &id) == 1) { 25 lock.l_type = F_WRLCK; 26 lock.l_whence = SEEK_SET; 27 lock.l_start = (id-START_ID)*sizeof(record); 28 lock.l_len = sizeof(record); 29 if (fcntl(fd,F_SETLKW, &lock) == -1) { /* 쓰기 잠금 */ 30 perror(argv[1]); 31 exit(3); 32 } 33

wrlock.c 34 lseek(fd, (long) (id-START_ID)*sizeof(record), SEEK_SET); 35 if ((read(fd, (char *) &record, sizeof(record)) > 0) && (record.id != 0)) 37 printf("이름:%s\t 학번:%d\t 점수:%d\n", 38 record.name, record.id, record.score); 39 else printf("레코드 %d 없음\n", id); 40 41 printf("새로운 점수: "); 42 scanf("%d", &record.score); 43 lseek(fd, (long) -sizeof(record), SEEK_CUR); 44 write(fd, (char *) &record, sizeof(record)); 45 46 lock.l_type = F_UNLCK; 47 fcntl(fd, F_SETLK, &lock); /* 잠금 해제 */ 48 printf("\n수정할 학생의 학번 입력:"); 49 } 51 close(fd); 52 exit(0); 53 }

잠금 함수 F_LOCK : 지정된 영역에 대해 잠금을 설정한다. 이미 잠금이 설정되어 있으면 잠금이 해제될 때까지 기다린다. F_TLOCK : 지정된 영역에 대해 잠금을 설정한다. 이미 잠금이 설정되어 있으면 기다리지 않고 오류(-1)를 반환한다. F_TEST : 지정된 영역이 잠금되어 있는지 검사한다. 잠금이 설정되어 있지 않으면 0을 반환하고 잠금이 설정되어 있으면 –1을 반환한다. F_ULOCK : 지정된 영역의 잠금을 해제한다. #include <unistd.h> int lockf(int fd, int cmd, off_t len); cmd에 따라 잠금 설정, 잠금 검사 혹은 잠금 해제 한다. 잠금 영역은 현재 파일 위치부터 len 길이 만큼이다. 성공하면 0 실패하면 –1을 반환한다.

wrlockf.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <fcntl.h> 5 #include "student.h" 6 #define START_ID 1201001 7 8 /* 잠금 함수를 이용한 학생 데이터베이스 수정 프로그램 */ 9 int main(int argc, char *argv[]) 10 { 11 int fd, id; 12 struct student record; 13 14 if (argc < 2) { 15 fprintf(stderr, "사용법 : %s file\n", argv[0]); 16 exit(1); 17 }

wrlockf.c 19 if ((fd = open(argv[1], O_RDWR)) == -1) { 20 perror(argv[1]); 21 exit(2); 22 } 23 24 printf("\n수정할 학생의 학번 입력:"); 25 while (scanf("%d", &id) == 1) { 26 lseek(fd, (long) (id-START_ID)*sizeof(record), SEEK_SET); 27 if (lockf(fd, F_LOCK, sizeof(record)) == -1) { // 쓰기 잠금 28 perror(argv[1]); 29 exit(3); 30 } 31 32 if ((read(fd, (char *) &record, sizeof(record)) > 0) && (record.id != 0)) 34 printf("이름:%s\t 학번:%d\t 점수:%d\n", 35 record.name, record.id, record.score); 36 else printf("레코드 %d 없음\n", id);

wrlockf.c 37 38 printf("새로운 점수: "); 39 scanf("%d", &record.score); 40 lseek(fd, (long) -sizeof(record), SEEK_CUR); 41 write(fd, (char *) &record, sizeof(record)); 42 43 lseek(fd, (long) (id-START_ID)*sizeof(record), SEEK_SET); 44 lockf(fd, F_ULOCK, sizeof(record)); // 잠금 해제 45 printf("\n수정할 학생의 학번 입력:"); 46 } 47 48 close(fd); 49 exit(0); 50 }

6.3 권고 잠금과 강제 잠금

권고 잠금과 강제 잠금 권고 잠금(advisory locking) 강제 잠금(mandatory locking) 지금까지 살펴본 잠금: 잠금을 할 수 있지만 강제되지는 않음. 즉 이미 잠금된 파일의 영역에 대해서도 잠금 규칙을 무시하고 읽 거나 쓰는 것이 가능 모든 관련 프로세스들이 자발적으로 잠금 규칙을 준수해야 한다. 강제 잠금(mandatory locking) 이미 잠금된 파일 영역에 대해 잠금 규칙을 무시하고 읽거나 쓰는 것이 불가능 커널이 잠금 규칙을 강제하므로 시스템의 부하가 증가 System V 계열에서 제공됨. Linux의 경우 파일 시스템을 마운트할 때 “-o mand” 옵션을 사용 해서 마운트해야 제공됨

강제 잠금 강제 잠금을 하는 방법 강제 잠금 규칙 해당 파일에 대해 set-group-ID 비트를 설정하고 group-execute 비트를 끄면 된다 $ chmod 2644 mandatory.txt $ ls -l mandatory.txt -rw-r-Sr-- 1 chang faculty 160 1월 31일 11:48 stdb1 강제 잠금 규칙 대상 영역의 현재 잠금 상태 넌블로킹 파일 디스크립터 블로킹 파일 디스크립터 읽기 쓰기 읽기 잠금 OK EAGAIN 블로킹 쓰기 잠금

file_lock.c #include <stdio.h> #include <fcntl.h> int main(int argc, char **argv) { static struct flock lock; int fd, ret, c; if (argc < 2) { fprintf(stderr, "사용법: %s 파일\n", argv[0]); exit(1); } fd = open(argv[1], O_WRONLY); if (fd == -1) { printf("파일 열기 실패 \n"); lock.l_type = F_WRLCK; lock.l_start = 0; lock.l_whence = SEEK_SET; lock.l_len = 0; lock.l_pid = getpid(); ret = fcntl(fd, F_SETLKW, &lock); if(ret == 0) { // 파일 잠금 성공하면 c = getchar(); }

핵심 개념 한 레코드 혹은 파일에 대한 읽기 잠금은 여러 프로세스가 공유할 수 있지만 쓰기 잠금은 공유할 수 없으며 한 프로세스만 가질 수 있다. fcntl() 시스템 호출을 이용하여 지정된 영역에 대해 잠금 검사, 잠금 설정 혹은 잠금 해제를 할 수 있다. lockf() 함수를 이용하여 지정된 영역에 대해 잠금 검사, 잠금 설정 혹은 잠금 해제를 할 수 있다