Linux 첫 게시글로 파일을 잠그는 일을 해보겠슴니다..
먼저
잠금( Lock ) : 2개 이상의 process 가 동시에 하나의 resource 에 접근하려고 할 때 생기는 문제점을 해결하기 위한 기법
위와 같이 2개의 프로세스가 한 파일에 동시에 접근하려 할때.. ( 2개 이상이 될 수 도 있겠죠 )
문제점이 발생합니다.
그래서 Lock 을 걸어서 생기는 문제점을 해결해 주어야 하는데요
위 사진은 프로세스 A가 lock 을 한 경우 입니다.
1. 프로세스A 가 Lock 을 걸고
2. read / write 실행
3. 이때 프로세스 B가 접근하려 하지만 A의 Lock이 걸려있으므로 현재 접근 불가
이때 B 는 2가지 경우를 생각해볼 수 있는데
3-1 ) B가 Lock 을 얻지못한다면 에러를 return
3-2 ) A가 Lock 을 풀때까지 B 는 대기 return ( 이때도 대기 또는 에러 리턴 이라는 2가지 선택 가능 )
4. A가 Lock 을 푸는순간 ( = UnLock ) B 는 이제 접근 하고 싶은 파일을 읽거나 쓸수 있음
5. B 도 Lock
.
.
이라는 순서를 거치게 됩니다.
잠금 구현 함수
int fcntl( int fd , int cmd, struct flock *lock )
- 파일 및 레코드 잠금을 구현할 수 있음
- fd 는 대상이 되는 파일 디스크립터
.
.
* 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; // 프로세스 번호. 검사에만 필요
};
* 잠금의 종류
1) F_RDLCK : 여러 프로세스가 공유 가능한 읽기 잠금
2) F_WELCK : 한 프로세스만 가질 수 있는 배타적인 쓰기 잠금
* cmd
- F_GETLK : 잠금을 검사
- F_SETLK : 잠금 설정 혹은 해제 -> Lock 을 걸려고 시도 했을 때 다른 프로세스가 이미 Lock이 걸려있으면 에러를 리턴 ( -1 반환 )
- F_SETLKW : 잠금 설정 ( 대기 버전 ) 혹은 해제 -> Lock 을 걸려고 시도 했을 때 다른 프로세스가 이미 Lock이 걸려있어도 대기 ( UnLock 이 되면 진입 )
Lock 의 예제를 살펴 보겠습니다 .
코드는 https://beej.us/guide/bgipc/html/multi/flocking.html 를 참고 했습니다 .
.
.
코드는
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
/* l_type l_whence l_start l_len l_pid */
struct flock fl = {F_WRLCK, SEEK_SET, 0, 0, 0 }; // 즉 처음부터 끝까지 // 파일전체를 잠금
int fd;
fl.l_pid = getpid(); // 굳이 필요는 없다..
if (argc > 1)
fl.l_type = F_RDLCK;
if ((fd = open("lockdemo.c", O_RDWR)) == -1) {
perror("open");
exit(1);
}
printf("Press <RETURN> to try to get lock: ");
getchar();
printf("Trying to get lock...");
if (fcntl(fd, F_SETLKW, &fl) == -1) { // 대기 , 잠금이 가능하면 fl 구조체처럼 잠금 설정지시
perror("fcntl");
exit(1);
}
printf("got lock\n");
printf("Press <RETURN> to release lock: ");
getchar();
fl.l_type = F_UNLCK; /* set to unlock same region */
if (fcntl(fd, F_SETLK, &fl) == -1) { // lock 을 거는 위치와 푸는 위치는 같다
perror("fcntl");
exit(1);
}
printf("Unlocked.\n");
close(fd);
return 0;
}
를 실행하면 잘 작동이 되는 것을 확인할 수 있습니다.
'Linux' 카테고리의 다른 글
#4 Linux ( 시그널-alarm() ) (0) | 2022.11.23 |
---|---|
#3 Linux ( 프로그램 실행 ) (0) | 2022.11.22 |
#2 Linux ( 프로세스 ) (0) | 2022.11.22 |